├── .gitattributes
├── KeyOnline.sln
├── KeyOnline
├── ConfigWin.Designer.cs
├── ConfigWin.cs
├── ConfigWin.resx
├── FingerPrint.cs
├── KeyOnline.cs
├── KeyOnline.csproj
├── KeyOnline.sln
├── Properties
│ └── AssemblyInfo.cs
├── README.md
├── StatusWin.Designer.cs
├── StatusWin.cs
├── StatusWin.resx
├── Toolbox.cs
└── Web References
│ └── KeyServerWS
│ ├── Default.disco
│ ├── Default.wsdl
│ ├── Reference.cs
│ └── Reference.map
├── KeyServer
├── Default.asmx
├── KeyServer.csproj
├── Keys.xml
├── Permissions.xml
├── Properties
│ └── AssemblyInfo.cs
├── README.md
├── Requests.xml
├── Soap.cs
└── Web.config
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
--------------------------------------------------------------------------------
/KeyOnline.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | # SharpDevelop 5.1
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeyOnline", "KeyOnline\KeyOnline.csproj", "{AB7F26CB-B578-4521-86ED-43875F238870}"
6 | EndProject
7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeyServer", "KeyServer\KeyServer.csproj", "{33B9B663-FC0E-4E7D-A1FB-79841C8428E2}"
8 | EndProject
9 | Global
10 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
11 | Debug|Any CPU = Debug|Any CPU
12 | Release|Any CPU = Release|Any CPU
13 | EndGlobalSection
14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
15 | {AB7F26CB-B578-4521-86ED-43875F238870}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
16 | {AB7F26CB-B578-4521-86ED-43875F238870}.Debug|Any CPU.Build.0 = Debug|Any CPU
17 | {AB7F26CB-B578-4521-86ED-43875F238870}.Release|Any CPU.ActiveCfg = Release|Any CPU
18 | {AB7F26CB-B578-4521-86ED-43875F238870}.Release|Any CPU.Build.0 = Release|Any CPU
19 | {33B9B663-FC0E-4E7D-A1FB-79841C8428E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20 | {33B9B663-FC0E-4E7D-A1FB-79841C8428E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
21 | {33B9B663-FC0E-4E7D-A1FB-79841C8428E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
22 | {33B9B663-FC0E-4E7D-A1FB-79841C8428E2}.Release|Any CPU.Build.0 = Release|Any CPU
23 | EndGlobalSection
24 | EndGlobal
25 |
--------------------------------------------------------------------------------
/KeyOnline/ConfigWin.Designer.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Patrice
4 | * Date: 04/06/2017
5 | * Time: 21:56
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | namespace KeyOnline.Forms
10 | {
11 | partial class ConfigWin
12 | {
13 | ///
14 | /// Designer variable used to keep track of non-visual components.
15 | ///
16 | private System.ComponentModel.IContainer components = null;
17 | private System.Windows.Forms.Label labelURL;
18 | private System.Windows.Forms.Label labelLogin;
19 | private System.Windows.Forms.Label labelPassword;
20 | private System.Windows.Forms.TextBox textBoxURL;
21 | private System.Windows.Forms.TextBox textBoxLogin;
22 | private System.Windows.Forms.TextBox textBoxPassword;
23 | private System.Windows.Forms.Button buttonOK;
24 | private System.Windows.Forms.Button buttonCancel;
25 |
26 | ///
27 | /// Disposes resources used by the form.
28 | ///
29 | /// true if managed resources should be disposed; otherwise, false.
30 | protected override void Dispose(bool disposing)
31 | {
32 | if (disposing) {
33 | if (components != null) {
34 | components.Dispose();
35 | }
36 | }
37 | base.Dispose(disposing);
38 | }
39 |
40 | ///
41 | /// This method is required for Windows Forms designer support.
42 | /// Do not change the method contents inside the source code editor. The Forms designer might
43 | /// not be able to load this method if it was changed manually.
44 | ///
45 | private void InitializeComponent()
46 | {
47 | this.labelURL = new System.Windows.Forms.Label();
48 | this.labelLogin = new System.Windows.Forms.Label();
49 | this.labelPassword = new System.Windows.Forms.Label();
50 | this.textBoxURL = new System.Windows.Forms.TextBox();
51 | this.textBoxLogin = new System.Windows.Forms.TextBox();
52 | this.textBoxPassword = new System.Windows.Forms.TextBox();
53 | this.buttonOK = new System.Windows.Forms.Button();
54 | this.buttonCancel = new System.Windows.Forms.Button();
55 | this.SuspendLayout();
56 | //
57 | // labelURL
58 | //
59 | this.labelURL.Location = new System.Drawing.Point(13, 13);
60 | this.labelURL.Name = "labelURL";
61 | this.labelURL.Size = new System.Drawing.Size(84, 17);
62 | this.labelURL.TabIndex = 0;
63 | this.labelURL.Text = "KeyServer URL";
64 | //
65 | // labelLogin
66 | //
67 | this.labelLogin.Location = new System.Drawing.Point(13, 39);
68 | this.labelLogin.Name = "labelLogin";
69 | this.labelLogin.Size = new System.Drawing.Size(84, 17);
70 | this.labelLogin.TabIndex = 1;
71 | this.labelLogin.Text = "Login";
72 | //
73 | // labelPassword
74 | //
75 | this.labelPassword.Location = new System.Drawing.Point(13, 65);
76 | this.labelPassword.Name = "labelPassword";
77 | this.labelPassword.Size = new System.Drawing.Size(84, 17);
78 | this.labelPassword.TabIndex = 2;
79 | this.labelPassword.Text = "Password";
80 | //
81 | // textBoxURL
82 | //
83 | this.textBoxURL.Location = new System.Drawing.Point(103, 10);
84 | this.textBoxURL.Name = "textBoxURL";
85 | this.textBoxURL.Size = new System.Drawing.Size(242, 20);
86 | this.textBoxURL.TabIndex = 3;
87 | //
88 | // textBoxLogin
89 | //
90 | this.textBoxLogin.Location = new System.Drawing.Point(103, 39);
91 | this.textBoxLogin.Name = "textBoxLogin";
92 | this.textBoxLogin.Size = new System.Drawing.Size(100, 20);
93 | this.textBoxLogin.TabIndex = 4;
94 | //
95 | // textBoxPassword
96 | //
97 | this.textBoxPassword.Location = new System.Drawing.Point(103, 66);
98 | this.textBoxPassword.Name = "textBoxPassword";
99 | this.textBoxPassword.Size = new System.Drawing.Size(100, 20);
100 | this.textBoxPassword.TabIndex = 5;
101 | this.textBoxPassword.UseSystemPasswordChar = true;
102 | //
103 | // buttonOK
104 | //
105 | this.buttonOK.Location = new System.Drawing.Point(218, 103);
106 | this.buttonOK.Name = "buttonOK";
107 | this.buttonOK.Size = new System.Drawing.Size(49, 23);
108 | this.buttonOK.TabIndex = 6;
109 | this.buttonOK.Text = "OK";
110 | this.buttonOK.UseVisualStyleBackColor = true;
111 | this.buttonOK.Click += new System.EventHandler(this.Button1Click);
112 | //
113 | // buttonCancel
114 | //
115 | this.buttonCancel.Location = new System.Drawing.Point(273, 103);
116 | this.buttonCancel.Name = "buttonCancel";
117 | this.buttonCancel.Size = new System.Drawing.Size(75, 23);
118 | this.buttonCancel.TabIndex = 7;
119 | this.buttonCancel.Text = "Cancel";
120 | this.buttonCancel.UseVisualStyleBackColor = true;
121 | this.buttonCancel.Click += new System.EventHandler(this.Button2Click);
122 | //
123 | // ConfigWin
124 | //
125 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
126 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
127 | this.ClientSize = new System.Drawing.Size(360, 138);
128 | this.Controls.Add(this.buttonCancel);
129 | this.Controls.Add(this.buttonOK);
130 | this.Controls.Add(this.textBoxPassword);
131 | this.Controls.Add(this.textBoxLogin);
132 | this.Controls.Add(this.textBoxURL);
133 | this.Controls.Add(this.labelPassword);
134 | this.Controls.Add(this.labelLogin);
135 | this.Controls.Add(this.labelURL);
136 | this.Name = "ConfigWin";
137 | this.Text = "KeyServer Configuration";
138 | this.ResumeLayout(false);
139 | this.PerformLayout();
140 |
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/KeyOnline/ConfigWin.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Patrice
4 | * Date: 04/06/2017
5 | * Time: 21:56
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Drawing;
11 | using System.Windows.Forms;
12 |
13 | using KeePass;
14 | using KeePass.Plugins;
15 |
16 | using KeyOnline;
17 |
18 | namespace KeyOnline.Forms
19 | {
20 | ///
21 | /// Description of ConfigWin.
22 | ///
23 | public partial class ConfigWin : Form
24 | {
25 | private IPluginHost m_host = null;
26 |
27 | // Constantes Fichier Config
28 | private string configBase;
29 | private string urlField;
30 | private string loginField;
31 | private string passwordField;
32 |
33 | public ConfigWin(IPluginHost host)
34 | {
35 | //
36 | // The InitializeComponent() call is required for Windows Forms designer support.
37 | //
38 | InitializeComponent();
39 |
40 | m_host = host;
41 |
42 | // Constantes Fichier Config
43 | configBase = "KeyServer.";
44 | urlField = configBase + "url";
45 | loginField = configBase + "login";
46 | passwordField = configBase + "Password";
47 | SecureString secPassword = new SecureString();
48 |
49 | // Lecture des informations de configuration
50 | this.textBoxURL.Text = m_host.CustomConfig.GetString(urlField);
51 | this.textBoxLogin.Text = m_host.CustomConfig.GetString(loginField);
52 | secPassword.Encrypted = m_host.CustomConfig.GetString(passwordField);
53 | this.textBoxPassword.Text = secPassword.Decrypted;
54 |
55 | //
56 | // TODO: Add constructor code after the InitializeComponent() call.
57 | //
58 | }
59 |
60 | void Button1Click(object sender, EventArgs e)
61 | { // Bouton OK
62 |
63 | SecureString secPassword = new SecureString();
64 |
65 | // Ecriture des informations de configuration
66 | m_host.CustomConfig.SetString(urlField,this.textBoxURL.Text);
67 | m_host.CustomConfig.SetString(loginField,this.textBoxLogin.Text);
68 | secPassword.Decrypted = this.textBoxPassword.Text;
69 | m_host.CustomConfig.SetString(passwordField,secPassword.Encrypted);
70 |
71 | // Fermeture de la fenêtre
72 | this.Close();
73 | }
74 |
75 | void Button2Click(object sender, EventArgs e)
76 | { // Bouton Annuler
77 | this.Close();
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/KeyOnline/ConfigWin.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/KeyOnline/FingerPrint.cs:
--------------------------------------------------------------------------------
1 | /*
2 | Code from : https://www.codeproject.com/Articles/28678/Generating-Unique-Key-Finger-Print-for-a-Computer
3 |
4 | Introduction
5 | For licensing purposes, according to me, the best and secure way is to generate a unique key
6 | for the client's machine and provide a corresponding license key for that key. For this purpose,
7 | you can take help of the unique id of the client's computer motherboard, BIOS and processor.
8 | When you get these IDs, you can generate any key of your preferable format.
9 |
10 | Year ago, I found a very handy and useful code in C# by searching the Internet to get these IDs.
11 | And it's serving me perfectly so far. Thanks to the original author of the code.
12 |
13 | I added some additional code to generate a 128 bit key of a machine. The output is a nice looking
14 | key in hexadecimal format (eg. 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9).
15 |
16 | Suggestions
17 | I have a few suggestions in this regard:
18 |
19 | Generate a key from only the Motherboard, Processor and BIOS since the user normally doesn't
20 | change these parts.
21 | Don't use MAC ID, Graphics Card ID AND Disk ID since it's very common to change these devices.
22 | It takes significant time to get IDs of devices. So make the finger print generating function
23 | static and save it in a static variable so that it generates the key only once in the whole application.
24 | */
25 |
26 | using System;
27 | using System.Management;
28 | using System.Security.Cryptography;
29 | using System.Security;
30 | using System.Collections;
31 | using System.Text;
32 |
33 | namespace Security
34 | {
35 | ///
36 | /// Generates a 16 byte Unique Identification code of a computer
37 | /// Example: 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9
38 | ///
39 | public class FingerPrint
40 | {
41 | private static string fingerPrint = string.Empty;
42 | public string Value()
43 | {
44 | if (string.IsNullOrEmpty(fingerPrint))
45 | {
46 | fingerPrint = GetHash("CPU >> " + cpuId() + "\nBIOS >> " + biosId() + "\nBASE >> " + baseId()
47 | +"\nDISK >> "+ diskId() + "\nVIDEO >> " + videoId() +"\nMAC >> "+ macId()
48 | );
49 | // fingerPrint = "CPU >> " + cpuId() + "\nBIOS >> " + biosId() + "\nBASE >> " + baseId()
50 | // +"\nDISK >> "+ diskId() + "\nVIDEO >> " + videoId() +"\nMAC >> "+ macId();
51 | }
52 | return fingerPrint;
53 | }
54 | private static string GetHash(string s)
55 | {
56 | MD5 sec = new MD5CryptoServiceProvider();
57 | ASCIIEncoding enc = new ASCIIEncoding();
58 | byte[] bt = enc.GetBytes(s);
59 | return GetHexString(sec.ComputeHash(bt));
60 | }
61 | private static string GetHexString(byte[] bt)
62 | {
63 | string s = string.Empty;
64 | for (int i = 0; i < bt.Length; i++)
65 | {
66 | byte b = bt[i];
67 | int n, n1, n2;
68 | n = (int)b;
69 | n1 = n & 15;
70 | n2 = (n >> 4) & 15;
71 | if (n2 > 9)
72 | s += ((char)(n2 - 10 + (int)'A')).ToString();
73 | else
74 | s += n2.ToString();
75 | if (n1 > 9)
76 | s += ((char)(n1 - 10 + (int)'A')).ToString();
77 | else
78 | s += n1.ToString();
79 | if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-";
80 | }
81 | return s;
82 | }
83 | #region Original Device ID Getting Code
84 | //Return a hardware identifier
85 | private static string identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue)
86 | {
87 | string result = "";
88 | System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
89 | System.Management.ManagementObjectCollection moc = mc.GetInstances();
90 | foreach (System.Management.ManagementObject mo in moc)
91 | {
92 | if (mo[wmiMustBeTrue].ToString() == "True")
93 | {
94 | //Only get the first one
95 | if (result == "")
96 | {
97 | try
98 | {
99 | result = mo[wmiProperty].ToString();
100 | break;
101 | }
102 | catch
103 | {
104 | }
105 | }
106 | }
107 | }
108 | return result;
109 | }
110 | //Return a hardware identifier
111 | private static string identifier(string wmiClass, string wmiProperty)
112 | {
113 | string result = "";
114 | System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass);
115 | System.Management.ManagementObjectCollection moc = mc.GetInstances();
116 | foreach (System.Management.ManagementObject mo in moc)
117 | {
118 | //Only get the first one
119 | if (result == "")
120 | {
121 | try
122 | {
123 | result = mo[wmiProperty].ToString();
124 | break;
125 | }
126 | catch
127 | {
128 | }
129 | }
130 | }
131 | return result;
132 | }
133 | private static string cpuId()
134 | {
135 | //Uses first CPU identifier available in order of preference
136 | //Don't get all identifiers, as very time consuming
137 | string retVal = identifier("Win32_Processor", "UniqueId");
138 | if (retVal == "") //If no UniqueID, use ProcessorID
139 | {
140 | retVal = identifier("Win32_Processor", "ProcessorId");
141 | if (retVal == "") //If no ProcessorId, use Name
142 | {
143 | retVal = identifier("Win32_Processor", "Name");
144 | if (retVal == "") //If no Name, use Manufacturer
145 | {
146 | retVal = identifier("Win32_Processor", "Manufacturer");
147 | }
148 | //Add clock speed for extra security
149 | retVal += identifier("Win32_Processor", "MaxClockSpeed");
150 | }
151 | }
152 | return retVal;
153 | }
154 | //BIOS Identifier
155 | private static string biosId()
156 | {
157 | return identifier("Win32_BIOS", "Manufacturer")
158 | + identifier("Win32_BIOS", "SMBIOSBIOSVersion")
159 | + identifier("Win32_BIOS", "IdentificationCode")
160 | + identifier("Win32_BIOS", "SerialNumber")
161 | + identifier("Win32_BIOS", "ReleaseDate")
162 | + identifier("Win32_BIOS", "Version");
163 | }
164 | //Main physical hard drive ID
165 | private static string diskId()
166 | {
167 | return identifier("Win32_DiskDrive", "Model")
168 | + identifier("Win32_DiskDrive", "Manufacturer")
169 | + identifier("Win32_DiskDrive", "Signature")
170 | + identifier("Win32_DiskDrive", "TotalHeads");
171 | }
172 | //Motherboard ID
173 | private static string baseId()
174 | {
175 | return identifier("Win32_BaseBoard", "Model")
176 | + identifier("Win32_BaseBoard", "Manufacturer")
177 | + identifier("Win32_BaseBoard", "Name")
178 | + identifier("Win32_BaseBoard", "SerialNumber");
179 | }
180 | //Primary video controller ID
181 | private static string videoId()
182 | {
183 | return identifier("Win32_VideoController", "DriverVersion")
184 | + identifier("Win32_VideoController", "Name");
185 | }
186 | //First enabled network card ID
187 | private static string macId()
188 | {
189 | return identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled");
190 | }
191 | #endregion
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/KeyOnline/KeyOnline.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Patrice
4 | * Date: 28/05/2017
5 | * Time: 16:41
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.IO;
11 | using System.Net;
12 | using System.Text;
13 | using System.Windows.Forms;
14 | //using System.Management;
15 | using Security;
16 |
17 | using KeePass.App;
18 | using KeePass.Plugins;
19 | using KeePassLib.Keys;
20 |
21 | using KeyOnline.Forms;
22 |
23 | namespace KeyOnline
24 | {
25 | public sealed class KeyOnlineExt : Plugin
26 | {
27 | private IPluginHost m_host = null;
28 | private KeyOnline m_provider = null;
29 |
30 | // Objects for menu items
31 | private ToolStripSeparator m_tsSeparator = null;
32 | private ToolStripMenuItem m_tsmiMenuItem = null;
33 |
34 | public override bool Initialize(IPluginHost host)
35 | {
36 | m_provider = new KeyOnline(host);
37 | m_host = host;
38 |
39 | // Add Key Provider
40 | m_host.KeyProviderPool.Add(m_provider);
41 |
42 | // Add "KeyServer Configuration" to the Tools menu
43 | AddConfigMenu();
44 |
45 | return true;
46 | }
47 |
48 | public override void Terminate()
49 | {
50 | // Remove all of our menu items
51 | ToolStripItemCollection tsMenu = m_host.MainWindow.ToolsMenu.DropDownItems;
52 | m_tsmiMenuItem.Click -= this.OpenConfigForm;
53 | tsMenu.Remove(m_tsmiMenuItem);
54 | tsMenu.Remove(m_tsSeparator);
55 |
56 | // Remove KeyProvider
57 | m_host.KeyProviderPool.Remove(m_provider);
58 | }
59 |
60 | // Open KeyServer Configuration Form
61 | private void OpenConfigForm(object sender, EventArgs e)
62 | {
63 | ConfigWin ConfigForm = new ConfigWin(m_host);
64 | ConfigForm.ShowDialog();
65 | }
66 |
67 | // Add "KeyServer Configuration" to the Tools menu
68 | private void AddConfigMenu()
69 | {
70 | // Get a reference to the 'Tools' menu item container
71 | ToolStripItemCollection tsMenu = m_host.MainWindow.ToolsMenu.DropDownItems;
72 |
73 | // Add a separator at the bottom
74 | m_tsSeparator = new ToolStripSeparator();
75 | tsMenu.Add(m_tsSeparator);
76 |
77 | // Add menu item
78 | m_tsmiMenuItem = new ToolStripMenuItem();
79 | m_tsmiMenuItem.Text = "Configure KeyServer";
80 | m_tsmiMenuItem.Click += this.OpenConfigForm;
81 | tsMenu.Add(m_tsmiMenuItem);
82 | }
83 | }
84 |
85 | public sealed class KeyOnline : KeyProvider
86 | {
87 | private IPluginHost m_host = null;
88 |
89 | // Constants
90 | // Name of custom items in Keepass.config.xml
91 | const string configBase = "KeyServer.";
92 | const string urlField = configBase + "url";
93 | const string loginField = configBase + "login";
94 | const string passwordField = configBase + "Password";
95 |
96 | // HarwareId generated during plugin initialization
97 | private string HardwareId = string.Empty;
98 |
99 | ///
100 | /// Init: Calculate hardwareid.
101 | ///
102 | public KeyOnline(IPluginHost host)
103 | {
104 | m_host = host;
105 | FingerPrint clFingerPrint = new FingerPrint();
106 | HardwareId = clFingerPrint.Value();
107 | }
108 |
109 | public override string Name
110 | {
111 | get { return "KeyOnline Key Provider"; }
112 | }
113 |
114 | public override byte[] GetKey(KeyProviderQueryContext ctx)
115 | {
116 | //Apply Policy restrictions.
117 | PolicyApply();
118 |
119 | SecureString secPassword = new SecureString();
120 |
121 | // Reads config values for Keepass.config.xml
122 | string ksURL = m_host.CustomConfig.GetString(urlField);
123 | string ksLogin = m_host.CustomConfig.GetString(loginField);
124 | string ksPassword = m_host.CustomConfig.GetString(passwordField);
125 |
126 | // Open config window if a parameter is missing
127 | if ((ksURL == null) || (ksLogin == null) || (ksPassword == null))
128 | {
129 | ConfigWin ConfigForm = new ConfigWin(m_host);
130 | ConfigForm.ShowDialog();
131 |
132 | ksURL = m_host.CustomConfig.GetString(urlField);
133 | ksLogin = m_host.CustomConfig.GetString(loginField);
134 | ksPassword = m_host.CustomConfig.GetString(passwordField);
135 | }
136 |
137 | // Open Debug Window
138 | StatusWin StatusForm = new StatusWin();
139 | StatusForm.Show();
140 |
141 | // Create Webservice object
142 | StatusForm.StatusLog.Text = "Invoking Web Service...";
143 | KeyServerWS.Soap ksws = new KeyServerWS.Soap();
144 | // Use URL from Keepass.config.xml
145 | ksws.Url = ksURL;
146 | StatusForm.StatusLog.AppendText("Done\r\n");
147 |
148 | // Retrieve database filename
149 | string dbFilename = Path.GetFileName(ctx.DatabasePath);
150 | StatusForm.StatusLog.AppendText("Querying key with parameters :\r\n");
151 | StatusForm.StatusLog.AppendText(String.Format(" - FileName : {0}\r\n",dbFilename));
152 | StatusForm.StatusLog.AppendText(String.Format(" - UserName : {0}\r\n",ksLogin));
153 | StatusForm.StatusLog.AppendText(String.Format(" - HadwareId : {0}\r\n",HardwareId));
154 |
155 | string dbKey = null;
156 | try {
157 | secPassword.Encrypted = ksPassword;
158 | NetworkCredential ksCreds = new NetworkCredential();
159 | ksCreds.UserName = ksLogin;
160 | ksCreds.Password = secPassword.Decrypted;
161 | ksws.Credentials = ksCreds;
162 | dbKey = ksws.GetKey(dbFilename,ksLogin,HardwareId);
163 | StatusForm.StatusLog.AppendText("Done\r\n");
164 | StatusForm.StatusLog.AppendText(String.Format("Key Found : {0}\r\n",dbKey));
165 | } catch (Exception) {
166 | MessageBox.Show("Connection Error...\r\nCheck configuration.\r\n(Tools / Configure KeyServer)");
167 | StatusForm.Close();
168 | return null;
169 | }
170 |
171 | if (dbKey == String.Empty)
172 | {
173 | MessageBox.Show("Error : Access denied or database not found");
174 | StatusForm.Close();
175 | return null;
176 | }
177 |
178 | return Encoding.ASCII.GetBytes(dbKey);
179 | }
180 |
181 | // Apply restricted Plugin Policy
182 | private void PolicyApply()
183 | {
184 | KeePass.App.AppPolicy.Current.ChangeMasterKey = false;
185 | KeePass.App.AppPolicy.Current.ChangeMasterKeyNoKey = false;
186 | KeePass.App.AppPolicy.Current.Export = false;
187 | KeePass.App.AppPolicy.Current.ExportNoKey = false;
188 | KeePass.App.AppPolicy.Current.Print = false;
189 | KeePass.App.AppPolicy.Current.PrintNoKey = false;
190 | KeePass.App.AppPolicy.Current.UnhidePasswords = false;
191 | KeePass.App.AppPolicy.Current.EditTriggers = false;
192 | KeePass.App.AppPolicy.Current.CopyWholeEntries = false;
193 |
194 | EventHandler ehEditEntryOpen = delegate(object sender, KeePass.UI.GwmWindowEventArgs e)
195 | {
196 | if (e.Form.Name=="PwEntryForm") { KeePass.App.AppPolicy.Current.UnhidePasswords = true; }
197 | };
198 | KeePass.UI.GlobalWindowManager.WindowAdded += ehEditEntryOpen;
199 | EventHandler ehEditEntryClose = delegate(object sender, KeePass.UI.GwmWindowEventArgs e)
200 | {
201 | if (e.Form.Name=="PwEntryForm") { KeePass.App.AppPolicy.Current.UnhidePasswords = false; }
202 | };
203 | KeePass.UI.GlobalWindowManager.WindowRemoved += ehEditEntryClose;
204 | }
205 |
206 | }
207 | }
208 |
209 |
--------------------------------------------------------------------------------
/KeyOnline/KeyOnline.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {AB7F26CB-B578-4521-86ED-43875F238870}
5 | {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
6 | Debug
7 | AnyCPU
8 | Library
9 | KeyOnline
10 | KeyOnline
11 | v2.0
12 | Properties
13 | False
14 | False
15 | False
16 |
17 |
18 |
19 | AnyCPU
20 |
21 |
22 | bin\Debug\
23 | True
24 | Full
25 | False
26 | True
27 | DEBUG;TRACE
28 |
29 |
30 | bin\Release\
31 | False
32 | None
33 | True
34 | False
35 | TRACE
36 |
37 |
38 |
39 | ..\..\Build\KeePass\Debug\KeePass.exe
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | ConfigWin.cs
54 |
55 |
56 |
57 |
58 |
59 |
60 | StatusWin.cs
61 |
62 |
63 | True
64 | True
65 | Reference.map
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | ConfigWin.cs
74 |
75 |
76 | StatusWin.cs
77 |
78 |
79 |
80 |
81 | Static
82 | http://localhost/Default.asmx
83 | Web References\KeyServerWS
84 | KeyOnline.KeyServerWS
85 |
86 |
87 |
88 |
89 |
90 |
91 | MSDiscoCodeGenerator
92 | Reference.cs
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/KeyOnline/KeyOnline.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | # SharpDevelop 5.1
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeyOnline", "KeyOnline.csproj", "{AB7F26CB-B578-4521-86ED-43875F238870}"
6 | EndProject
7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeyOnlineWS", "..\KeyOnlineWS\KeyOnlineWS.csproj", "{05209D0D-79DC-4F13-8E3D-C64946AFCE46}"
8 | EndProject
9 | Global
10 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
11 | Debug|Any CPU = Debug|Any CPU
12 | Release|Any CPU = Release|Any CPU
13 | EndGlobalSection
14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
15 | {AB7F26CB-B578-4521-86ED-43875F238870}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
16 | {AB7F26CB-B578-4521-86ED-43875F238870}.Debug|Any CPU.Build.0 = Debug|Any CPU
17 | {AB7F26CB-B578-4521-86ED-43875F238870}.Release|Any CPU.ActiveCfg = Release|Any CPU
18 | {AB7F26CB-B578-4521-86ED-43875F238870}.Release|Any CPU.Build.0 = Release|Any CPU
19 | {05209D0D-79DC-4F13-8E3D-C64946AFCE46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
20 | {05209D0D-79DC-4F13-8E3D-C64946AFCE46}.Debug|Any CPU.Build.0 = Debug|Any CPU
21 | {05209D0D-79DC-4F13-8E3D-C64946AFCE46}.Release|Any CPU.ActiveCfg = Release|Any CPU
22 | {05209D0D-79DC-4F13-8E3D-C64946AFCE46}.Release|Any CPU.Build.0 = Release|Any CPU
23 | EndGlobalSection
24 | EndGlobal
25 |
--------------------------------------------------------------------------------
/KeyOnline/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | #region Using directives
2 | using System;
3 | using System.Reflection;
4 | using System.Runtime.InteropServices;
5 |
6 | #endregion
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle ("KeyOnline")]
11 | [assembly: AssemblyDescription ("Securely grab database keys online")]
12 | [assembly: AssemblyConfiguration ("")]
13 | [assembly: AssemblyCompany ("Patrice LE TEXIER")]
14 | [assembly: AssemblyProduct ("KeePass Plugin")]
15 | [assembly: AssemblyCopyright ("Copyright 2017")]
16 | [assembly: AssemblyTrademark ("")]
17 | [assembly: AssemblyCulture ("")]
18 | // This sets the default COM visibility of types in the assembly to invisible.
19 | // If you need to expose a type to COM, use [ComVisible(true)] on that type.
20 | [assembly: ComVisible (false)]
21 | // The assembly version has following format :
22 | //
23 | // Major.Minor.Build.Revision
24 | //
25 | // You can specify all the values or you can use the default the Revision and
26 | // Build Numbers by using the '*' as shown below:
27 | [assembly: AssemblyVersion ("1.0.*")]
28 |
--------------------------------------------------------------------------------
/KeyOnline/README.md:
--------------------------------------------------------------------------------
1 | # Client part
2 |
3 | This is the client part. This plugin is installed in Keepass.
4 |
--------------------------------------------------------------------------------
/KeyOnline/StatusWin.Designer.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Patrice
4 | * Date: 31/05/2017
5 | * Time: 21:42
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | namespace KeyOnline
10 | {
11 | partial class StatusWin
12 | {
13 | ///
14 | /// Designer variable used to keep track of non-visual components.
15 | ///
16 | private System.ComponentModel.IContainer components = null;
17 | public System.Windows.Forms.TextBox StatusLog;
18 |
19 | ///
20 | /// Disposes resources used by the form.
21 | ///
22 | /// true if managed resources should be disposed; otherwise, false.
23 | protected override void Dispose(bool disposing)
24 | {
25 | if (disposing) {
26 | if (components != null) {
27 | components.Dispose();
28 | }
29 | }
30 | base.Dispose(disposing);
31 | }
32 |
33 | ///
34 | /// This method is required for Windows Forms designer support.
35 | /// Do not change the method contents inside the source code editor. The Forms designer might
36 | /// not be able to load this method if it was changed manually.
37 | ///
38 | private void InitializeComponent()
39 | {
40 | this.StatusLog = new System.Windows.Forms.TextBox();
41 | this.SuspendLayout();
42 | //
43 | // StatusLog
44 | //
45 | this.StatusLog.Location = new System.Drawing.Point(12, 12);
46 | this.StatusLog.Multiline = true;
47 | this.StatusLog.Name = "StatusLog";
48 | this.StatusLog.Size = new System.Drawing.Size(313, 116);
49 | this.StatusLog.TabIndex = 0;
50 | this.StatusLog.TextChanged += new System.EventHandler(this.TextBox1TextChanged);
51 | //
52 | // StatusWin
53 | //
54 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
55 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
56 | this.ClientSize = new System.Drawing.Size(337, 140);
57 | this.Controls.Add(this.StatusLog);
58 | this.Name = "StatusWin";
59 | this.Text = "StatusWin";
60 | this.ResumeLayout(false);
61 | this.PerformLayout();
62 |
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/KeyOnline/StatusWin.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Patrice
4 | * Date: 31/05/2017
5 | * Time: 21:42
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Drawing;
11 | using System.Windows.Forms;
12 |
13 | namespace KeyOnline
14 | {
15 | ///
16 | /// Description of StatusWin.
17 | ///
18 | public partial class StatusWin : Form
19 | {
20 | public StatusWin()
21 | {
22 | //
23 | // The InitializeComponent() call is required for Windows Forms designer support.
24 | //
25 | InitializeComponent();
26 |
27 | //
28 | // TODO: Add constructor code after the InitializeComponent() call.
29 | //
30 | }
31 | void TextBox1TextChanged(object sender, EventArgs e)
32 | {
33 |
34 | }
35 | void StatusOkClick(object sender, EventArgs e)
36 | {
37 |
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/KeyOnline/StatusWin.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/KeyOnline/Toolbox.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Patrice
4 | * Date: 10/06/2017
5 | * Time: 10:30
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Text;
11 | using System.Security.Cryptography;
12 |
13 | namespace KeyOnline
14 | {
15 | public class SecureString
16 | {
17 | ///
18 | /// Entropy byte array for data encryption
19 | ///
20 | private byte[] EncryptEntropy = { 1, 2, 3, 5, 7, 11, 13, 17 };
21 | private string EncryptedValue = string.Empty;
22 |
23 | ///
24 | /// Function EncryptStringLocalUser
25 | /// Encrypts a string using local user information
26 | ///
27 |
28 | public string Encrypted
29 | {
30 | get { return this.EncryptedValue; }
31 | set { this.EncryptedValue = value; }
32 | }
33 |
34 | public string Decrypted
35 | {
36 | get { return this.Decrypt(this.EncryptedValue); }
37 | set { this.EncryptedValue = this.Encrypt(value); }
38 | }
39 |
40 | private string Encrypt(string inputstr)
41 | {
42 | // Convert password to UTF8 byte array;
43 | byte[] PasswordDecrypted = Encoding.UTF8.GetBytes(inputstr);
44 | // Encrypt Password using local user informations
45 | byte[] PasswordEncrypted = ProtectedData.Protect(PasswordDecrypted,EncryptEntropy,DataProtectionScope.CurrentUser);
46 | // Clear decrypted password array for security
47 | Array.Clear(PasswordDecrypted,0,PasswordDecrypted.Length);
48 | // Convert Encrypted Password to Base64 for easy storage
49 | string PasswordFinal = Convert.ToBase64String(PasswordEncrypted);
50 | // Clear Encrypted Password array for security
51 | Array.Clear(PasswordEncrypted,0,PasswordEncrypted.Length);
52 |
53 | return PasswordFinal;
54 | }
55 |
56 | ///
57 | /// Function DecryptStringLocalUser
58 | /// Decrypts a string using local user information
59 | ///
60 | private string Decrypt(string inputstr)
61 | {
62 | // Convert Password to byte array
63 | byte[] PasswordEncrypted = Convert.FromBase64String(inputstr);
64 | // Decrypt Password using local user informations
65 | byte[] PasswordDecrypted = ProtectedData.Unprotect(PasswordEncrypted,EncryptEntropy,DataProtectionScope.CurrentUser);
66 | // Clear PasswordEncrypted for security
67 | Array.Clear(PasswordEncrypted,0,PasswordEncrypted.Length);
68 | // Convert password to UTF8 string
69 | string PasswordFinal = Encoding.UTF8.GetString(PasswordDecrypted);
70 | // Clear PasswordDecrypted for security
71 | Array.Clear(PasswordDecrypted,0,PasswordDecrypted.Length);
72 |
73 | return PasswordFinal;
74 | }
75 |
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/KeyOnline/Web References/KeyServerWS/Default.disco:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/KeyOnline/Web References/KeyServerWS/Default.wsdl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
--------------------------------------------------------------------------------
/KeyOnline/Web References/KeyServerWS/Reference.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace KeyOnline.KeyServerWS {
12 | using System;
13 | using System.Web.Services;
14 | using System.Diagnostics;
15 | using System.Web.Services.Protocols;
16 | //using System.Xml.Serialization;
17 | using System.ComponentModel;
18 |
19 |
20 | ///
21 | [System.CodeDom.Compiler.GeneratedCodeAttribute("SharpDevelop", "5.1.0.5216-0e58df71")]
22 | [System.Diagnostics.DebuggerStepThroughAttribute()]
23 | [System.ComponentModel.DesignerCategoryAttribute("code")]
24 | [System.Web.Services.WebServiceBindingAttribute(Name="SoapSoap", Namespace="http://tempuri.org/")]
25 | public partial class Soap : System.Web.Services.Protocols.SoapHttpClientProtocol {
26 |
27 | ///
28 | public Soap() {
29 | this.Url = "http://localhost/Default.asmx";
30 | }
31 |
32 | ///
33 | [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/Login", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
34 | public bool Login(string userName, string password) {
35 | object[] results = this.Invoke("Login", new object[] {
36 | userName,
37 | password});
38 | return ((bool)(results[0]));
39 | }
40 |
41 | ///
42 | public System.IAsyncResult BeginLogin(string userName, string password, System.AsyncCallback callback, object asyncState) {
43 | return this.BeginInvoke("Login", new object[] {
44 | userName,
45 | password}, callback, asyncState);
46 | }
47 |
48 | ///
49 | public bool EndLogin(System.IAsyncResult asyncResult) {
50 | object[] results = this.EndInvoke(asyncResult);
51 | return ((bool)(results[0]));
52 | }
53 |
54 | ///
55 | [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/Logout", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
56 | public void Logout() {
57 | this.Invoke("Logout", new object[0]);
58 | }
59 |
60 | ///
61 | public System.IAsyncResult BeginLogout(System.AsyncCallback callback, object asyncState) {
62 | return this.BeginInvoke("Logout", new object[0], callback, asyncState);
63 | }
64 |
65 | ///
66 | public void EndLogout(System.IAsyncResult asyncResult) {
67 | this.EndInvoke(asyncResult);
68 | }
69 |
70 | ///
71 | [System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/GetKey", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
72 | public string GetKey(string db, string username, string hardwareid) {
73 | object[] results = this.Invoke("GetKey", new object[] {
74 | db,
75 | username,
76 | hardwareid});
77 | return ((string)(results[0]));
78 | }
79 |
80 | ///
81 | public System.IAsyncResult BeginGetKey(string db, string username, string hardwareid, System.AsyncCallback callback, object asyncState) {
82 | return this.BeginInvoke("GetKey", new object[] {
83 | db,
84 | username,
85 | hardwareid}, callback, asyncState);
86 | }
87 |
88 | ///
89 | public string EndGetKey(System.IAsyncResult asyncResult) {
90 | object[] results = this.EndInvoke(asyncResult);
91 | return ((string)(results[0]));
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/KeyOnline/Web References/KeyServerWS/Reference.map:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/KeyServer/Default.asmx:
--------------------------------------------------------------------------------
1 | <%@ WebService Language="C#" Class="KeyServer.Soap" %>
--------------------------------------------------------------------------------
/KeyServer/KeyServer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {33B9B663-FC0E-4E7D-A1FB-79841C8428E2}
5 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
6 | Debug
7 | AnyCPU
8 | Library
9 | KeyServer
10 | KeyServer
11 | Properties
12 |
13 |
14 | AnyCPU
15 |
16 |
17 | bin\
18 | True
19 | Full
20 | False
21 | True
22 | DEBUG;TRACE
23 |
24 |
25 | bin\
26 | False
27 | None
28 | True
29 | False
30 | TRACE
31 |
32 |
33 |
34 | 4.0
35 |
36 |
37 |
38 | 3.5
39 |
40 |
41 |
42 | 3.5
43 |
44 |
45 |
46 |
47 |
48 |
49 | 3.5
50 |
51 |
52 |
53 |
54 |
55 | Default.asmx
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/KeyServer/Keys.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | Db1.db
20 | AZERTYUIOP
21 |
22 |
23 | NewDatabase.kdbx
24 | 44444444
25 |
26 |
--------------------------------------------------------------------------------
/KeyServer/Permissions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | NewDatabase.kdbx
21 | VM-Win7\Patrice
22 | 94E4-DD7F-BFB0-502C-10DD-8453-B122-7D34
23 |
24 |
25 | NewDatabase.kdbx
26 | User2
27 | 94E4-DD7F-BFB0-502C-10DD-8453-B122-7D34
28 |
29 |
--------------------------------------------------------------------------------
/KeyServer/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | #region Using directives
2 |
3 | using System;
4 | using System.Reflection;
5 | using System.Runtime.InteropServices;
6 |
7 | #endregion
8 |
9 | // General Information about an assembly is controlled through the following
10 | // set of attributes. Change these attribute values to modify the information
11 | // associated with an assembly.
12 | [assembly: AssemblyTitle("KeyServer")]
13 | [assembly: AssemblyDescription("")]
14 | [assembly: AssemblyConfiguration("")]
15 | [assembly: AssemblyCompany("")]
16 | [assembly: AssemblyProduct("KeyServer")]
17 | [assembly: AssemblyCopyright("Copyright 2017")]
18 | [assembly: AssemblyTrademark("")]
19 | [assembly: AssemblyCulture("")]
20 |
21 | // This sets the default COM visibility of types in the assembly to invisible.
22 | // If you need to expose a type to COM, use [ComVisible(true)] on that type.
23 | [assembly: ComVisible(false)]
24 |
25 | // The assembly version has following format :
26 | //
27 | // Major.Minor.Build.Revision
28 | //
29 | // You can specify all the values or you can use the default the Revision and
30 | // Build Numbers by using the '*' as shown below:
31 | [assembly: AssemblyVersion("1.0.*")]
32 |
--------------------------------------------------------------------------------
/KeyServer/README.md:
--------------------------------------------------------------------------------
1 | # Server part
2 |
3 | This is the server part. This part is hosted on a web server, and is used to authenticate the user and the device trying to open a protected database.
4 |
5 | For testing purpose, i run this part on Cassini Web Server.
6 | (https://cassinidev.codeplex.com/)
7 | I use it with the following parameters :
8 | - Physical Path = root of KeyServer folder
9 | - VirtualPath = /
10 | - Port = Specific / 80
11 | - HostName = (empty)
12 | - Options : NTLM Authentication Required
13 |
14 | The file "Permissions.xml" contains hardwareid and usernames allowed to access a database.
15 | The file "Keys.xml" contains database names and keys.
16 | The file "Requests.xml" logs keys requests.
17 |
18 | # THIS CODE IS ONLY FOR TESTING PURPOSES.
19 | # DO NOT USE PRODUCTION DATA.
20 |
--------------------------------------------------------------------------------
/KeyServer/Requests.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | NewDatabase.kdbx
21 | VM-Win7\Patrice
22 | 94E4-DD7F-BFB0-502C-10DD-8453-B122-7D34
23 |
24 |
--------------------------------------------------------------------------------
/KeyServer/Soap.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Created by SharpDevelop.
3 | * User: Patrice
4 | * Date: 31/05/2017
5 | * Time: 19:48
6 | *
7 | * To change this template use Tools | Options | Coding | Edit Standard Headers.
8 | */
9 | using System;
10 | using System.Data;
11 | using System.IO;
12 | using System.Web;
13 | using System.Web.Services;
14 | using System.Web.Services.Protocols;
15 |
16 | namespace KeyServer
17 | {
18 | [WebService]
19 | public class Soap : System.Web.Services.WebService
20 | {
21 | // Path of XML files
22 | const string XmlPath = @"C:\@Almeria\KeePass\KeyOnline\KeyServer\";
23 |
24 | ///
25 | /// Logs into the web service
26 | ///
27 | /// The User Name to login in as
28 | /// User's password
29 | /// True on successful login.
30 | // [WebMethod(EnableSession=true)]
31 | // public bool Login(string userName, string password)
32 | // {
33 | // //NOTE: There are better ways of doing authentication. This is just illustrates Session usage.
34 | // UserName = userName;
35 | // return true;
36 | // }
37 |
38 | ///
39 | /// Logs out of the Session.
40 | ///
41 | // [WebMethod(EnableSession=true)]
42 | // public void Logout()
43 | // {
44 | // Context.Session.Abandon();
45 | // }
46 |
47 | ///
48 | /// Main Method
49 | /// Check permissions and return key.
50 | ///
51 | [WebMethod(EnableSession=true)]
52 | public string GetKey(string db, string hardwareid)
53 | {
54 | // Log request
55 | DataTable RequestLog = CreateLogTable();
56 | DataRow RequestLogRow;
57 |
58 | RequestLogRow = RequestLog.NewRow();
59 | RequestLogRow["db"] = db;
60 | RequestLogRow["user"] = UserName;
61 | RequestLogRow["hardwareid"] = hardwareid;
62 | RequestLog.Rows.Add(RequestLogRow);
63 |
64 | string RequestLogPath = XmlPath + "Requests.xml";
65 | FileStream RequestLogStream = File.Create(RequestLogPath);
66 | RequestLog.WriteXml(RequestLogStream,XmlWriteMode.WriteSchema);
67 | RequestLogStream.Close();
68 |
69 | // Check permission in permission.xml
70 | if (CheckPermission(db,UserName,hardwareid))
71 | {
72 | return GetDbKey(db);
73 | }
74 | else
75 | {
76 | return string.Empty;
77 | }
78 | }
79 |
80 | ///
81 | /// UserName of the logged in user.
82 | ///
83 | private string UserName {
84 | get {return (string)User.Identity.Name;}
85 | //get {return (string)Context.Session["User"];}
86 | //set {Context.Session["User"] = value;}
87 | }
88 |
89 | ///
90 | /// Returns the key of the specified db
91 | ///
92 | private string GetDbKey(string db)
93 | {
94 | DataTable DbKeys = new DataTable();
95 | string Key = string.Empty;
96 | DbKeys.ReadXml(XmlPath + "Keys.xml");
97 |
98 | DataRow[] foundRows = DbKeys.Select("db = '" + db + "'");
99 | if ( foundRows.Length > 0 )
100 | {
101 | Key = (string)foundRows[0][1];
102 | }
103 | return Key;
104 | }
105 |
106 | ///
107 | /// Checks if the specified user and hardwareid is allowed to open the specified db.
108 | /// Returns true when a result is found.
109 | ///
110 | private Boolean CheckPermission(string db, string username, string hardwareid)
111 | {
112 | DataTable Permissions = new DataTable();
113 | Permissions.ReadXml(XmlPath + "Permissions.xml");
114 |
115 | DataRow[] foundRows;
116 | foundRows = Permissions.Select("db = '" + db + "' AND user='" + username + "' AND hardwareid = '" + hardwareid + "'");
117 |
118 | return (foundRows.Length > 0);
119 | }
120 |
121 | ///
122 | /// Returns a DataTable to log requests
123 | /// Columns :
124 | /// - db = Filename (ex : mypasswords.kdbx)
125 | /// - user = username
126 | /// - hardwareid = 16 byte Unique Identification code of a computer
127 | /// Example: 4876-8DB5-EE85-69D3-FE52-8CF7-395D-2EA9
128 | ///
129 | private DataTable CreateLogTable()
130 | {
131 | DataTable RequestLog = new DataTable("RequestLog");
132 | DataColumn column;
133 |
134 | column = new DataColumn();
135 | column.DataType = Type.GetType("System.String");
136 | column.ColumnName = "db";
137 | RequestLog.Columns.Add(column);
138 |
139 | column = new DataColumn();
140 | column.DataType = Type.GetType("System.String");
141 | column.ColumnName = "user";
142 | RequestLog.Columns.Add(column);
143 |
144 | column = new DataColumn();
145 | column.DataType = Type.GetType("System.String");
146 | column.ColumnName = "hardwareid";
147 | RequestLog.Columns.Add(column);
148 |
149 | return RequestLog;
150 | }
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/KeyServer/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
12 |
13 |
18 |
19 |
31 |
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KeePassKeyServer
2 |
3 | Keepass-KeyServer is a key provider plugin for KeePass.
4 |
5 | # NOT FOR PRODUCTION USE
6 | # DO NOT USE WITH SENSITIVE DATA
7 |
8 | The goal is to manage database access over the internet, using a remote "key server".
9 |
10 | I'm working with a team of technicians, which copy password databases on their laptop.
11 | I want to control the diffusion of such informations, and eventualy revoke access to a database.
12 | (if a technician leaves the company for example).
13 |
14 | The plugin will send informations to the key server to authenticate :
15 | - the computer (using a hardware id)
16 | - the user (using a username / password)
17 | - the location ? (using ip address of the client)
18 |
19 | The plugin could also check :
20 | - keepass and plugin version (using certificate thumbprint of keepass and plugin executables for example ?)
21 | - if a validated keepass policy is enforced, to disable features like changing the master key, export and synchronisation features, triggers, ...
22 |
--------------------------------------------------------------------------------