diff --git a/KeePassHttp.plgx b/KeePassHttp.plgx index 52609af..9687963 100644 Binary files a/KeePassHttp.plgx and b/KeePassHttp.plgx differ diff --git a/KeePassHttp/ConfigOpt.cs b/KeePassHttp/ConfigOpt.cs index 3f6d6b6..2ff8a22 100644 --- a/KeePassHttp/ConfigOpt.cs +++ b/KeePassHttp/ConfigOpt.cs @@ -13,6 +13,7 @@ public class ConfigOpt const string SearchInAllOpenedDatabasesKey = "KeePassHttp_SearchInAllOpenedDatabases"; const string MatchSchemesKey = "KeePassHttp_MatchSchemes"; const string ReturnStringFieldsKey = "KeePassHttp_ReturnStringFields"; + const string ReturnStringFieldsWithKphOnlyKey = "KeePassHttp_ReturnStringFieldsWithKphOnly"; const string SortResultByUsernameKey = "KeePassHttp_SortResultByUsername"; const string ListenerPortKey = "KeePassHttp_ListenerPort"; const string ListenerHostKey = "KeePassHttp_ListenerHost"; @@ -70,6 +71,12 @@ public bool ReturnStringFields set { _config.SetBool(ReturnStringFieldsKey, value); } } + public bool ReturnStringFieldsWithKphOnly + { + get { return _config.GetBool(ReturnStringFieldsWithKphOnlyKey, true); } + set { _config.SetBool(ReturnStringFieldsWithKphOnlyKey, value); } + } + public bool SortResultByUsername { get { return _config.GetBool(SortResultByUsernameKey, true); } diff --git a/KeePassHttp/Handlers.cs b/KeePassHttp/Handlers.cs index 8c446f3..7527497 100644 --- a/KeePassHttp/Handlers.cs +++ b/KeePassHttp/Handlers.cs @@ -113,6 +113,145 @@ private void GetAllLoginsHandler(Request r, Response resp, Aes aes) } } + private void GetLoginsCustomSearchHandler(Request r, Response resp, Aes aes) + { + if (!VerifyRequest(r, aes)) + return; + + string clientId = r.Id; + + string searchString = null; + if (r.SearchString != null) + searchString = CryptoTransform(r.SearchString, true, false, aes, CMode.DECRYPT); + + var items = FindMatchingEntriesLikeSearchbox(r, aes); + if (items.ToList().Count > 0) + { + Func filter = delegate (PwEntry e) + { + var c = GetEntryConfig(e); + if (c != null) + { + return !c.Allow.Contains(clientId); + } + return true; + }; + + var configOpt = new ConfigOpt(this.host.CustomConfig); + var config = GetConfigEntry(true); + var autoAllowS = config.Strings.ReadSafe("Auto Allow"); + var autoAllow = autoAllowS != null && autoAllowS.Trim() != ""; + autoAllow = autoAllow || configOpt.AlwaysAllowAccess; + var needPrompting = from e in items where filter(e.entry) select e; + + if (needPrompting.ToList().Count > 0 && !autoAllow) + { + var win = this.host.MainWindow; + + using (var f = new AccessControlForm()) + { + win.Invoke((MethodInvoker)delegate + { + f.Icon = win.Icon; + f.Plugin = this; + f.Entries = (from e in items where filter(e.entry) select e.entry).ToList(); + f.Host = clientId; + f.Load += delegate { f.Activate(); }; + f.ShowDialog(win); + if (f.Remember && (f.Allowed || f.Denied)) + { + foreach (var e in needPrompting) + { + var c = GetEntryConfig(e.entry); + if (c == null) + c = new KeePassHttpEntryConfig(); + var set = f.Allowed ? c.Allow : c.Deny; + set.Add(clientId); + SetEntryConfig(e.entry, c); + } + } + if (!f.Allowed) + { + items = items.Except(needPrompting); + } + }); + } + } + + var itemsList = items.ToList(); + + if (configOpt.SpecificMatchingOnly) + { + itemsList = (from e in itemsList + orderby e.entry.UsageCount ascending + select e).ToList(); + + ulong lowestDistance = itemsList[0].entry.UsageCount; + + itemsList = (from e in itemsList + where e.entry.UsageCount == lowestDistance + orderby e.entry.UsageCount + select e).ToList(); + + } + + if (configOpt.SortResultByUsername) + { + var items2 = from e in itemsList orderby e.entry.UsageCount ascending, GetUserPass(e)[0] ascending select e; + itemsList = items2.ToList(); + } + else + { + var items2 = from e in itemsList orderby e.entry.UsageCount ascending, e.entry.Strings.ReadSafe(PwDefs.TitleField) ascending select e; + itemsList = items2.ToList(); + } + + foreach (var entryDatabase in itemsList) + { + var e = PrepareElementForResponseEntries(configOpt, entryDatabase); + resp.Entries.Add(e); + } + + if (itemsList.Count > 0) + { + var names = (from e in resp.Entries select e.Name).Distinct(); + var n = String.Join("\n ", names.ToArray()); + + if (configOpt.ReceiveCredentialNotification) + ShowNotification(String.Format("{0}: is receiving credentials for:\n {1}", r.Id, n)); + } + + resp.Success = true; + resp.Id = r.Id; + SetResponseVerifier(resp, aes); + + foreach (var entry in resp.Entries) + { + entry.Name = CryptoTransform(entry.Name, false, true, aes, CMode.ENCRYPT); + entry.Login = CryptoTransform(entry.Login, false, true, aes, CMode.ENCRYPT); + entry.Uuid = CryptoTransform(entry.Uuid, false, true, aes, CMode.ENCRYPT); + entry.Password = CryptoTransform(entry.Password, false, true, aes, CMode.ENCRYPT); + + if (entry.StringFields != null) + { + foreach (var sf in entry.StringFields) + { + sf.Key = CryptoTransform(sf.Key, false, true, aes, CMode.ENCRYPT); + sf.Value = CryptoTransform(sf.Value, false, true, aes, CMode.ENCRYPT); + } + } + } + + resp.Count = resp.Entries.Count; + } + else + { + resp.Success = true; + resp.Id = r.Id; + SetResponseVerifier(resp, aes); + } + } + private IEnumerable FindMatchingEntries(Request r, Aes aes) { string submitHost = null; @@ -237,6 +376,54 @@ private IEnumerable FindMatchingEntries(Request r, Aes aes) return result; } + private IEnumerable FindMatchingEntriesLikeSearchbox(Request r, Aes aes) + { + string searchString = null; + string realm = null; + var listResult = new List(); + if (r.SearchString != null) + { + searchString = CryptoTransform(r.SearchString, true, false, aes, CMode.DECRYPT); + } + + if (r.Realm != null) + realm = CryptoTransform(r.Realm, true, false, aes, CMode.DECRYPT); + + var parms = MakeSearchParametersLikeSearchBox(); + + List listDatabases = new List(); + + var configOpt = new ConfigOpt(this.host.CustomConfig); + if (configOpt.SearchInAllOpenedDatabases) + { + foreach (PwDocument doc in host.MainWindow.DocumentManager.Documents) + { + if (doc.Database.IsOpen) + { + listDatabases.Add(doc.Database); + } + } + } + else + { + listDatabases.Add(host.Database); + } + + int listCount = 0; + foreach (PwDatabase db in listDatabases) + { + parms.SearchString = searchString; + var listEntries = new PwObjectList(); + db.RootGroup.SearchEntries(parms, listEntries); + foreach (var le in listEntries) + { + listResult.Add(new PwEntryDatabase(le, db)); + } + } + + return listResult; + } + private void GetLoginsCountHandler(Request r, Response resp, Aes aes) { if (!VerifyRequest(r, aes)) @@ -470,10 +657,17 @@ private ResponseEntry PrepareElementForResponseEntries(ConfigOpt configOpt, PwEn fields = new List(); foreach (var sf in entryDatabase.entry.Strings) { - if (sf.Key.StartsWith("KPH: ")) + var sfValue = entryDatabase.entry.Strings.ReadSafe(sf.Key); + if (configOpt.ReturnStringFieldsWithKphOnly) + { + if (sf.Key.StartsWith("KPH: ")) + { + fields.Add(new ResponseStringField(sf.Key.Substring(5), sfValue)); + } + } + else { - var sfValue = entryDatabase.entry.Strings.ReadSafe(sf.Key); - fields.Add(new ResponseStringField(sf.Key.Substring(5), sfValue)); + fields.Add(new ResponseStringField(sf.Key, sfValue)); } } diff --git a/KeePassHttp/KeePassHttp.cs b/KeePassHttp/KeePassHttp.cs index 832c582..9006b7e 100644 --- a/KeePassHttp/KeePassHttp.cs +++ b/KeePassHttp/KeePassHttp.cs @@ -73,6 +73,22 @@ private SearchParameters MakeSearchParameters() return p; } + private SearchParameters MakeSearchParametersLikeSearchBox() + { + var p = new SearchParameters(); + p.SearchInTitles = true; + p.RegularExpression = false; + p.SearchInGroupNames = true; + p.SearchInNotes = true; + p.SearchInOther = true; + p.SearchInPasswords = true; + p.SearchInTags = true; + p.SearchInUrls = true; + p.SearchInUserNames = true; + p.SearchInUuids = true; + return p; + } + private string CryptoTransform(string input, bool base64in, bool base64out, Aes cipher, CMode mode) { byte[] bytes; @@ -192,6 +208,7 @@ public override bool Initialize(IPluginHost host) handlers.Add(Request.TEST_ASSOCIATE, TestAssociateHandler); handlers.Add(Request.ASSOCIATE, AssociateHandler); handlers.Add(Request.GET_LOGINS, GetLoginsHandler); + handlers.Add(Request.GET_LOGINS_CUSTOM_SEARCH, GetLoginsCustomSearchHandler); handlers.Add(Request.GET_LOGINS_COUNT, GetLoginsCountHandler); handlers.Add(Request.GET_ALL_LOGINS, GetAllLoginsHandler); handlers.Add(Request.SET_LOGIN, SetLoginHandler); diff --git a/KeePassHttp/OptionsForm.Designer.cs b/KeePassHttp/OptionsForm.Designer.cs index e04938f..e5a8f0d 100644 --- a/KeePassHttp/OptionsForm.Designer.cs +++ b/KeePassHttp/OptionsForm.Designer.cs @@ -28,7 +28,6 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OptionsForm)); this.cancelButton = new System.Windows.Forms.Button(); this.okButton = new System.Windows.Forms.Button(); this.tabControl1 = new System.Windows.Forms.TabControl(); @@ -42,6 +41,7 @@ private void InitializeComponent() this.credMatchingCheckbox = new System.Windows.Forms.CheckBox(); this.credNotifyCheckbox = new System.Windows.Forms.CheckBox(); this.tabPage2 = new System.Windows.Forms.TabPage(); + this.returnStringFieldsWithKphOnlyCheckBox = new System.Windows.Forms.CheckBox(); this.hostName = new System.Windows.Forms.TextBox(); this.label10 = new System.Windows.Forms.Label(); this.label8 = new System.Windows.Forms.Label(); @@ -68,7 +68,7 @@ private void InitializeComponent() // this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.cancelButton.Location = new System.Drawing.Point(313, 488); + this.cancelButton.Location = new System.Drawing.Point(313, 508); this.cancelButton.Name = "cancelButton"; this.cancelButton.Size = new System.Drawing.Size(88, 28); this.cancelButton.TabIndex = 2; @@ -80,7 +80,7 @@ private void InitializeComponent() this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK; this.okButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.okButton.Location = new System.Drawing.Point(219, 488); + this.okButton.Location = new System.Drawing.Point(219, 508); this.okButton.Name = "okButton"; this.okButton.Size = new System.Drawing.Size(88, 28); this.okButton.TabIndex = 1; @@ -90,15 +90,15 @@ private void InitializeComponent() // // tabControl1 // - this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.tabControl1.Controls.Add(this.tabPage1); this.tabControl1.Controls.Add(this.tabPage2); this.tabControl1.Location = new System.Drawing.Point(1, 3); this.tabControl1.Name = "tabControl1"; this.tabControl1.SelectedIndex = 0; - this.tabControl1.Size = new System.Drawing.Size(410, 478); + this.tabControl1.Size = new System.Drawing.Size(410, 498); this.tabControl1.TabIndex = 3; // // tabPage1 @@ -114,7 +114,7 @@ private void InitializeComponent() this.tabPage1.Location = new System.Drawing.Point(4, 22); this.tabPage1.Name = "tabPage1"; this.tabPage1.Padding = new System.Windows.Forms.Padding(3); - this.tabPage1.Size = new System.Drawing.Size(402, 434); + this.tabPage1.Size = new System.Drawing.Size(402, 497); this.tabPage1.TabIndex = 0; this.tabPage1.Text = "General"; this.tabPage1.UseVisualStyleBackColor = true; @@ -149,13 +149,13 @@ private void InitializeComponent() this.matchSchemesCheckbox.Size = new System.Drawing.Size(375, 30); this.matchSchemesCheckbox.TabIndex = 17; this.matchSchemesCheckbox.Text = "&Match URL schemes\r\nonly entries with the same scheme (http://, https://, ftp://," + - " ...) are returned"; + " ...) are returned"; this.matchSchemesCheckbox.UseVisualStyleBackColor = true; // // removePermissionsButton // - this.removePermissionsButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.removePermissionsButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.removePermissionsButton.ImageAlign = System.Drawing.ContentAlignment.TopLeft; this.removePermissionsButton.Location = new System.Drawing.Point(14, 216); this.removePermissionsButton.Name = "removePermissionsButton"; @@ -177,8 +177,8 @@ private void InitializeComponent() // // removeButton // - this.removeButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.removeButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); this.removeButton.Location = new System.Drawing.Point(14, 182); this.removeButton.Name = "removeButton"; this.removeButton.Size = new System.Drawing.Size(372, 28); @@ -195,7 +195,7 @@ private void InitializeComponent() this.credMatchingCheckbox.Size = new System.Drawing.Size(238, 30); this.credMatchingCheckbox.TabIndex = 9; this.credMatchingCheckbox.Text = "&Return only best matching entries for an URL\r\ninstead of all entries for the who" + - "le domain"; + "le domain"; this.credMatchingCheckbox.UseVisualStyleBackColor = true; // // credNotifyCheckbox @@ -210,6 +210,7 @@ private void InitializeComponent() // // tabPage2 // + this.tabPage2.Controls.Add(this.returnStringFieldsWithKphOnlyCheckBox); this.tabPage2.Controls.Add(this.hostName); this.tabPage2.Controls.Add(this.label10); this.tabPage2.Controls.Add(this.label8); @@ -229,14 +230,25 @@ private void InitializeComponent() this.tabPage2.Location = new System.Drawing.Point(4, 22); this.tabPage2.Name = "tabPage2"; this.tabPage2.Padding = new System.Windows.Forms.Padding(3); - this.tabPage2.Size = new System.Drawing.Size(402, 452); + this.tabPage2.Size = new System.Drawing.Size(402, 472); this.tabPage2.TabIndex = 1; this.tabPage2.Text = "Advanced"; this.tabPage2.UseVisualStyleBackColor = true; // + // returnStringFieldsWithKphOnlyCheckBox + // + this.returnStringFieldsWithKphOnlyCheckBox.AutoSize = true; + this.returnStringFieldsWithKphOnlyCheckBox.Location = new System.Drawing.Point(55, 215); + this.returnStringFieldsWithKphOnlyCheckBox.Name = "returnStringFieldsWithKphOnlyCheckBox"; + this.returnStringFieldsWithKphOnlyCheckBox.Size = new System.Drawing.Size(300, 30); + this.returnStringFieldsWithKphOnlyCheckBox.TabIndex = 31; + this.returnStringFieldsWithKphOnlyCheckBox.Text = "Only return advanced string fields which start with \"KPH: \"\r\n(Mind the space afte" + + "r KPH:)"; + this.returnStringFieldsWithKphOnlyCheckBox.UseVisualStyleBackColor = true; + // // hostName // - this.hostName.Location = new System.Drawing.Point(45, 296); + this.hostName.Location = new System.Drawing.Point(48, 318); this.hostName.Name = "hostName"; this.hostName.Size = new System.Drawing.Size(103, 20); this.hostName.TabIndex = 25; @@ -246,28 +258,28 @@ private void InitializeComponent() // label10 // this.label10.AutoSize = true; - this.label10.Location = new System.Drawing.Point(4, 261); + this.label10.Location = new System.Drawing.Point(7, 283); this.label10.Name = "label10"; this.label10.Size = new System.Drawing.Size(375, 26); this.label10.TabIndex = 23; this.label10.Text = "Only change the host to bind to if you want to give access to other computers.\r\nU" + - "se \'*\' to bind it to all your IP addresses (potentially dangerous!)\r\n"; + "se \'*\' to bind it to all your IP addresses (potentially dangerous!)\r\n"; // // label8 // this.label8.AutoSize = true; - this.label8.Location = new System.Drawing.Point(154, 296); + this.label8.Location = new System.Drawing.Point(157, 318); this.label8.Name = "label8"; this.label8.Size = new System.Drawing.Size(244, 65); this.label8.TabIndex = 26; this.label8.Text = "Default: localhost\r\nYou might need to run KeePass as administrator \r\nwhen you cha" + - "nge this.\r\nAlso don\'t forget to open the firewall if you want to \r\nbe able to us" + - "e it from a different computer."; + "nge this.\r\nAlso don\'t forget to open the firewall if you want to \r\nbe able to us" + + "e it from a different computer."; // // label9 // this.label9.AutoSize = true; - this.label9.Location = new System.Drawing.Point(7, 299); + this.label9.Location = new System.Drawing.Point(10, 321); this.label9.Name = "label9"; this.label9.Size = new System.Drawing.Size(32, 13); this.label9.TabIndex = 24; @@ -276,16 +288,16 @@ private void InitializeComponent() // label7 // this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(154, 393); + this.label7.Location = new System.Drawing.Point(157, 415); this.label7.Name = "label7"; this.label7.Size = new System.Drawing.Size(241, 39); this.label7.TabIndex = 30; this.label7.Text = "Default: 19455\r\nDon\'t forget to change the port number also in\r\nthe plugins like " + - "chromeIPass, PassIFox, kypass,..."; + "chromeIPass, PassIFox, kypass,..."; // // portNumber // - this.portNumber.Location = new System.Drawing.Point(45, 393); + this.portNumber.Location = new System.Drawing.Point(48, 415); this.portNumber.Maximum = new decimal(new int[] { 99999, 0, @@ -309,7 +321,7 @@ private void InitializeComponent() // label5 // this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(5, 371); + this.label5.Location = new System.Drawing.Point(8, 393); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(312, 13); this.label5.TabIndex = 27; @@ -318,7 +330,7 @@ private void InitializeComponent() // label6 // this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(10, 395); + this.label6.Location = new System.Drawing.Point(13, 417); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(29, 13); this.label6.TabIndex = 28; @@ -328,7 +340,7 @@ private void InitializeComponent() // this.label4.AutoSize = true; this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.label4.Location = new System.Drawing.Point(53, 225); + this.label4.Location = new System.Drawing.Point(52, 248); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(277, 26); this.label4.TabIndex = 22; @@ -339,19 +351,22 @@ private void InitializeComponent() this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(52, 156); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(302, 65); + this.label3.Size = new System.Drawing.Size(289, 52); this.label3.TabIndex = 21; - this.label3.Text = resources.GetString("label3.Text"); + this.label3.Text = "If there are more fields needed than username + password,\r\nnormal \"String Fields\"" + + " are used, which can be defined in the\r\n\"Advanced\" tab of an entry.\r\nString fiel" + + "ds are returned in alphabetical order."; // // returnStringFieldsCheckbox // this.returnStringFieldsCheckbox.AutoSize = true; this.returnStringFieldsCheckbox.Location = new System.Drawing.Point(7, 136); this.returnStringFieldsCheckbox.Name = "returnStringFieldsCheckbox"; - this.returnStringFieldsCheckbox.Size = new System.Drawing.Size(303, 17); + this.returnStringFieldsCheckbox.Size = new System.Drawing.Size(186, 17); this.returnStringFieldsCheckbox.TabIndex = 20; - this.returnStringFieldsCheckbox.Text = "&Return also advanced string fields which start with \"KPH: \""; + this.returnStringFieldsCheckbox.Text = "&Return also advanced string fields"; this.returnStringFieldsCheckbox.UseVisualStyleBackColor = true; + this.returnStringFieldsCheckbox.CheckedChanged += new System.EventHandler(this.returnStringFieldsCheckbox_CheckedChanged); // // label2 // @@ -409,7 +424,7 @@ private void InitializeComponent() this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.cancelButton; - this.ClientSize = new System.Drawing.Size(411, 525); + this.ClientSize = new System.Drawing.Size(411, 545); this.Controls.Add(this.tabControl1); this.Controls.Add(this.okButton); this.Controls.Add(this.cancelButton); @@ -461,5 +476,6 @@ private void InitializeComponent() private System.Windows.Forms.Label label10; private System.Windows.Forms.Label label8; private System.Windows.Forms.Label label9; + private System.Windows.Forms.CheckBox returnStringFieldsWithKphOnlyCheckBox; } } \ No newline at end of file diff --git a/KeePassHttp/OptionsForm.cs b/KeePassHttp/OptionsForm.cs index a24b4eb..171601a 100644 --- a/KeePassHttp/OptionsForm.cs +++ b/KeePassHttp/OptionsForm.cs @@ -43,10 +43,13 @@ private void OptionsForm_Load(object sender, EventArgs e) credSearchInAllOpenedDatabases.Checked = _config.SearchInAllOpenedDatabases; matchSchemesCheckbox.Checked = _config.MatchSchemes; returnStringFieldsCheckbox.Checked = _config.ReturnStringFields; + returnStringFieldsWithKphOnlyCheckBox.Checked = _config.ReturnStringFieldsWithKphOnly; SortByUsernameRadioButton.Checked = _config.SortResultByUsername; SortByTitleRadioButton.Checked = !_config.SortResultByUsername; portNumber.Value = _config.ListenerPort; hostName.Text = _config.ListenerHost; + + this.returnStringFieldsCheckbox_CheckedChanged(null, EventArgs.Empty); } private void okButton_Click(object sender, EventArgs e) @@ -59,6 +62,7 @@ private void okButton_Click(object sender, EventArgs e) _config.SearchInAllOpenedDatabases = credSearchInAllOpenedDatabases.Checked; _config.MatchSchemes = matchSchemesCheckbox.Checked; _config.ReturnStringFields = returnStringFieldsCheckbox.Checked; + _config.ReturnStringFieldsWithKphOnly = returnStringFieldsWithKphOnlyCheckBox.Checked; _config.SortResultByUsername = SortByUsernameRadioButton.Checked; _config.ListenerPort = (int)portNumber.Value; _config.ListenerHost = hostName.Text; @@ -212,5 +216,10 @@ private void SetRestartRequired() { _restartRequired = (_config.ListenerPort != portNumber.Value) || (_config.ListenerHost != hostName.Text); } + + private void returnStringFieldsCheckbox_CheckedChanged(object sender, EventArgs e) + { + this.returnStringFieldsWithKphOnlyCheckBox.Enabled = this.returnStringFieldsCheckbox.Checked; + } } } diff --git a/KeePassHttp/OptionsForm.resx b/KeePassHttp/OptionsForm.resx index 4282a89..7080a7d 100644 --- a/KeePassHttp/OptionsForm.resx +++ b/KeePassHttp/OptionsForm.resx @@ -117,11 +117,4 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - If there are more fields needed than username + password, -normal "String Fields" are used, which can be defined in the -"Advanced" tab of an entry. -String fields are returned in alphabetical order and have to start -with "KPH: " (mind the space after KPH:). - \ No newline at end of file diff --git a/KeePassHttp/Protocol.cs b/KeePassHttp/Protocol.cs index af29db1..e13f3e6 100644 --- a/KeePassHttp/Protocol.cs +++ b/KeePassHttp/Protocol.cs @@ -60,6 +60,7 @@ private void SetResponseVerifier(Response r, Aes aes) public class Request { public const string GET_LOGINS = "get-logins"; + public const string GET_LOGINS_CUSTOM_SEARCH = "get-logins-custom-search"; public const string GET_LOGINS_COUNT = "get-logins-count"; public const string GET_ALL_LOGINS = "get-all-logins"; public const string SET_LOGIN = "set-login"; @@ -97,6 +98,11 @@ public class Request /// public string SubmitUrl; + /// + /// Always encrypted, used with get-logins-custom-search + /// + public string SearchString; + /// /// Send the AES key ID with the 'associate' request /// @@ -129,7 +135,7 @@ public Response(string request, string hash) { RequestType = request; - if (request == Request.GET_LOGINS || request == Request.GET_ALL_LOGINS || request == Request.GENERATE_PASSWORD) + if (request == Request.GET_LOGINS || request == Request.GET_ALL_LOGINS || request == Request.GENERATE_PASSWORD || request == Request.GET_LOGINS_CUSTOM_SEARCH) Entries = new List(); else Entries = null;