diff --git a/KeePassHttp.plgx b/KeePassHttp.plgx index 52609af..6e1cce5 100644 Binary files a/KeePassHttp.plgx and b/KeePassHttp.plgx differ diff --git a/KeePassHttp/Handlers.cs b/KeePassHttp/Handlers.cs index 8c446f3..3f9a19b 100644 --- a/KeePassHttp/Handlers.cs +++ b/KeePassHttp/Handlers.cs @@ -85,15 +85,10 @@ private void GetAllLoginsHandler(Request r, Response resp, Aes aes) if (!VerifyRequest(r, aes)) return; - var list = new PwObjectList(); - var root = host.Database.RootGroup; - var parms = MakeSearchParameters(); - - parms.SearchString = @"^[A-Za-z0-9:/-]+\.[A-Za-z0-9:/-]+$"; // match anything looking like a domain or url + var list = root.GetEntries(true); - root.SearchEntries(parms, list); foreach (var entry in list) { var name = entry.Strings.ReadSafe(PwDefs.TitleField); @@ -370,43 +365,7 @@ orderby e.entry.UsageCount 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}: {1} is receiving credentials for:\n {2}", r.Id, host, 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; + CompleteGetLoginsResult(itemsList,configOpt,resp,r.Id,host,aes); } else { @@ -456,6 +415,119 @@ private int LevenshteinDistance(string source, string target) return distance[currentRow, m]; } + private void CompleteGetLoginsResult(List itemsList, ConfigOpt configOpt, Response resp, String rId, String host, Aes aes) + { + 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) + { + String notificationMessage; + if (host == null) + { + notificationMessage = rId; + } + else + { + notificationMessage = String.Format("{0}: {1}", rId, host); + } + notificationMessage = String.Format("{0} is receiving credentials for:\n {1}", notificationMessage, n); + ShowNotification(notificationMessage); + } + } + + resp.Success = true; + resp.Id = rId; + 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; + } + + private void GetLoginsByNamesHandler(Request r, Response resp, Aes aes) + { + if (!VerifyRequest(r, aes)) + return; + + if (r.Names == null) + { + return; + } + List decryptedNames = new List(); + foreach (String name in r.Names) { + if (name != null) { + decryptedNames.Add(CryptoTransform(name, true, false, aes, CMode.DECRYPT)); + } + } + + 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); + } + + var listEntries = new List(); + foreach (PwDatabase db in listDatabases) + { + foreach (var le in db.RootGroup.GetEntries(true)) { + var title = le.Strings.ReadSafe(PwDefs.TitleField); + bool titleMatched = false; + if (title != null) { + foreach (String name in decryptedNames) + { + if (name.Equals(title)) + { + titleMatched = true; + break; + } + } + } + if (titleMatched) + { + listEntries.Add(new PwEntryDatabase(le, db)); + } + } + } + + CompleteGetLoginsResult(listEntries, configOpt, resp, r.Id, null, aes); + } + private ResponseEntry PrepareElementForResponseEntries(ConfigOpt configOpt, PwEntryDatabase entryDatabase) { var name = entryDatabase.entry.Strings.ReadSafe(PwDefs.TitleField); diff --git a/KeePassHttp/KeePassHttp.cs b/KeePassHttp/KeePassHttp.cs index 832c582..0c99986 100644 --- a/KeePassHttp/KeePassHttp.cs +++ b/KeePassHttp/KeePassHttp.cs @@ -192,6 +192,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_BY_NAMES, GetLoginsByNamesHandler); handlers.Add(Request.GET_LOGINS_COUNT, GetLoginsCountHandler); handlers.Add(Request.GET_ALL_LOGINS, GetAllLoginsHandler); handlers.Add(Request.SET_LOGIN, SetLoginHandler); diff --git a/KeePassHttp/Protocol.cs b/KeePassHttp/Protocol.cs index af29db1..b794778 100644 --- a/KeePassHttp/Protocol.cs +++ b/KeePassHttp/Protocol.cs @@ -61,6 +61,7 @@ public class Request { public const string GET_LOGINS = "get-logins"; public const string GET_LOGINS_COUNT = "get-logins-count"; + public const string GET_LOGINS_BY_NAMES = "get-logins-by-names"; public const string GET_ALL_LOGINS = "get-all-logins"; public const string SET_LOGIN = "set-login"; public const string ASSOCIATE = "associate"; @@ -92,6 +93,11 @@ public class Request /// public string Url; + /// + /// Always encrypted, used get-logins-by-names + /// + public List Names; + /// /// Always encrypted, used with get-login /// @@ -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.GET_LOGINS_BY_NAMES || request == Request.GENERATE_PASSWORD) Entries = new List(); else Entries = null;