private ResponseEntry PrepareElementForResponseEntries(ConfigOpt configOpt, PwEntryDatabase entryDatabase) { var name = entryDatabase.entry.Strings.ReadSafe(PwDefs.TitleField); var loginpass = GetUserPass(entryDatabase); var login = loginpass[0]; var passwd = loginpass[1]; var uuid = entryDatabase.entry.Uuid.ToHexString(); List <ResponseStringField> fields = null; if (configOpt.ReturnStringFields) { fields = new List <ResponseStringField>(); foreach (var sf in entryDatabase.entry.Strings) { if (sf.Key.StartsWith("KPH: ")) { var sfValue = entryDatabase.entry.Strings.ReadSafe(sf.Key); fields.Add(new ResponseStringField(sf.Key.Substring(5), sfValue)); } } if (fields.Count > 0) { var fields2 = from e2 in fields orderby e2.Key ascending select e2; fields = fields2.ToList <ResponseStringField>(); } else { fields = null; } } return(new ResponseEntry(name, login, passwd, uuid, fields)); }
private PwEntry GetConfigEntry(bool create) { var configOpt = new ConfigOpt(this.host.CustomConfig); var root = host.Database.RootGroup; var loc = root; if (!String.IsNullOrEmpty(configOpt.PleasantPasswordFolder)) { var priv = root.FindCreateGroup("Private Folders", false); loc = priv.FindCreateGroup(configOpt.PleasantPasswordFolder, false); } string UUIDstring = configOpt.PleasantPasswordUUID; byte[] uuidByte = new byte[UUIDstring.Length / 2]; for (int i = 0; i < UUIDstring.Length / 2; i++) { uuidByte[i] = byte.Parse(UUIDstring.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber); } var uuid = new PwUuid(uuidByte); var entry = loc.FindEntry(uuid, false); if (entry == null && create) { entry = new PwEntry(false, true); entry.Uuid = uuid; entry.Strings.Set(PwDefs.TitleField, new ProtectedString(false, KEEPASSHTTP_NAME)); loc.AddEntry(entry, true); UpdateUI(null); } return(entry); }
private void GetLoginsByNamesHandler(Request r, Response resp, Aes aes) { if (!VerifyRequest(r, aes)) { return; } if (r.Username == null) { return; } string decryptedUsername = CryptoTransform(r.Username, true, false, aes, CMode.DECRYPT); List <PwDatabase> listDatabases = new List <PwDatabase>(); 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 <PwEntryDatabase>(); foreach (PwDatabase db in listDatabases) { foreach (var le in db.RootGroup.GetEntries(true)) { var username = le.Strings.ReadSafe(PwDefs.TanIndexField); bool usernameMatched = false; if (username != null) { if (decryptedUsername.Equals(username, StringComparison.OrdinalIgnoreCase)) { usernameMatched = true; } } if (usernameMatched) { listEntries.Add(new PwEntryDatabase(le, db)); } } } CompleteGetLoginsResult(listEntries, configOpt, resp, r.Id, null, aes); }
private void CompleteGetLoginsResult(List <PwEntryDatabase> 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 <string>(); var n = String.Join("\n ", names.ToArray <string>()); 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.IsRecycled = CryptoTransform(entry.IsRecycled, false, true, aes, CMode.ENCRYPT); entry.Password = CryptoTransform(entry.Password, false, true, aes, CMode.ENCRYPT); entry.Group.Name = CryptoTransform(entry.Group.Name, false, true, aes, CMode.ENCRYPT); entry.Group.Uuid = CryptoTransform(entry.Group.Uuid, 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; }
public override bool Initialize(IPluginHost host) { var httpSupported = HttpListener.IsSupported; this.host = host; var optionsMenu = new ToolStripMenuItem("KeePassHttp Options..."); optionsMenu.Click += OnOptions_Click; optionsMenu.Image = KeePassHttp.Properties.Resources.earth_lock; //optionsMenu.Image = global::KeePass.Properties.Resources.B16x16_File_Close; this.host.MainWindow.ToolsMenu.DropDownItems.Add(optionsMenu); if (httpSupported) { try { handlers.Add(Request.TEST_ASSOCIATE, TestAssociateHandler); handlers.Add(Request.ASSOCIATE, AssociateHandler); handlers.Add(Request.GET_LOGINS, GetLoginsHandler); handlers.Add(Request.GET_LOGINS_BY_USERNAME, GetLoginsByNamesHandler); handlers.Add(Request.GET_LOGINS_COUNT, GetLoginsCountHandler); handlers.Add(Request.GET_ALL_LOGINS, GetAllLoginsHandler); handlers.Add(Request.SET_LOGIN, SetLoginHandler); handlers.Add(Request.GENERATE_PASSWORD, GeneratePassword); listener = new HttpListener(); var configOpt = new ConfigOpt(this.host.CustomConfig); listener.Prefixes.Add(HTTP_SCHEME + configOpt.ListenerHost + ":" + configOpt.ListenerPort.ToString() + "/"); //listener.Prefixes.Add(HTTPS_PREFIX + HTTPS_PORT + "/"); listener.Start(); httpThread = new Thread(new ThreadStart(Run)); httpThread.Start(); } catch (HttpListenerException e) { MessageBox.Show(host.MainWindow, "Unable to start HttpListener!\nDo you really have only one installation of KeePassHttp in your KeePass-directory?\n\n" + e, "Unable to start HttpListener", MessageBoxButtons.OK, MessageBoxIcon.Error ); } } else { MessageBox.Show(host.MainWindow, "The .NET HttpListener is not supported on your OS", ".NET HttpListener not supported", MessageBoxButtons.OK, MessageBoxIcon.Error ); } return(httpSupported); }
public OptionsForm(ConfigOpt config) { _config = config; InitializeComponent(); // Find all groups and add to comboBox. // Add one empty entry (for unsetting the root) RootGroup.Items.Add(new ComboBoxItem("", "")); // Display the group names + add Uuid values to item PwDatabase db = KeePass.Program.MainForm.DocumentManager.ActiveDatabase; foreach (PwGroup thisGroup in db.RootGroup.GetGroups(true)) RootGroup.Items.Add(new ComboBoxItem(thisGroup.Name, thisGroup.Uuid.ToHexString())); }
private ResponseEntry PrepareElementForResponseEntries(ConfigOpt configOpt, PwEntryDatabase entryDatabase) { SprContext ctx = new SprContext(entryDatabase.entry, entryDatabase.database, SprCompileFlags.All, false, false); var name = entryDatabase.entry.Strings.ReadSafe(PwDefs.TitleField); var loginpass = GetUserPass(entryDatabase, ctx); var login = loginpass[0]; var passwd = loginpass[1]; var uuid = entryDatabase.entry.Uuid.ToHexString(); var group = new ResponseGroupField(entryDatabase.entry.ParentGroup.GetFullPath("/", true), entryDatabase.entry.ParentGroup.Uuid.ToHexString()); List <ResponseStringField> fields = null; if (configOpt.ReturnStringFields) { fields = new List <ResponseStringField>(); foreach (var sf in entryDatabase.entry.Strings) { var sfValue = entryDatabase.entry.Strings.ReadSafe(sf.Key); // follow references sfValue = SprEngine.Compile(sfValue, ctx); if (configOpt.ReturnStringFieldsWithKphOnly) { if (sf.Key.StartsWith("KPH: ")) { fields.Add(new ResponseStringField(sf.Key.Substring(5), sfValue)); } } else { fields.Add(new ResponseStringField(sf.Key, sfValue)); } } if (fields.Count > 0) { var fields2 = from e2 in fields orderby e2.Key ascending select e2; fields = fields2.ToList <ResponseStringField>(); } else { fields = null; } } return(new ResponseEntry(name, login, passwd, uuid, group, fields, IsEntryRecycled(entryDatabase.entry))); }
private void GetLoginsHandler(Request r, Response resp, Aes aes) { if (!VerifyRequest(r, aes)) { return; } string submithost = null; var host = GetHost(CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT)); if (r.SubmitUrl != null) { submithost = GetHost(CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT)); } var items = FindMatchingEntries(r, aes); if (items.ToList().Count > 0) { Func <PwEntry, bool> filter = delegate(PwEntry e) { var c = GetEntryConfig(e); var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); if (c != null) { return(title != host && entryUrl != host && !c.Allow.Contains(host) || (submithost != null && !c.Allow.Contains(submithost) && submithost != title && submithost != entryUrl)); } return(title != host && entryUrl != host || (submithost != null && title != submithost && entryUrl != submithost)); }; 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.Entries = needPrompting.ToList(); f.Host = submithost != null ? submithost : host; 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(host); if (submithost != null && submithost != host) { set.Add(submithost); } SetEntryConfig(e.entry, c); } } if (!f.Allowed) { items = items.Except(needPrompting); } }); } } string compareToUrl = null; if (r.SubmitUrl != null) { compareToUrl = CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT); } if (String.IsNullOrEmpty(compareToUrl)) { compareToUrl = CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT); } compareToUrl = compareToUrl.ToLower(); foreach (var entryDatabase in items) { string entryUrl = String.Copy(entryDatabase.entry.Strings.ReadSafe(PwDefs.UrlField)); if (String.IsNullOrEmpty(entryUrl)) { entryUrl = entryDatabase.entry.Strings.ReadSafe(PwDefs.TitleField); } entryUrl = entryUrl.ToLower(); entryDatabase.entry.UsageCount = (ulong)LevenshteinDistance(compareToUrl, entryUrl); } var itemsList = items.ToList(); if (configOpt.SpecificMatchingOnly) { itemsList = (from e in itemsList orderby e.entry.UsageCount ascending select e).ToList(); ulong lowestDistance = itemsList.Count > 0 ? itemsList[0].entry.UsageCount : 0; 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 <string>(); var n = String.Join("\n ", names.ToArray <string>()); 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; } else { resp.Success = true; resp.Id = r.Id; SetResponseVerifier(resp, aes); } }
private void _RequestHandler(IAsyncResult r) { if (stopped) { return; } var l = (HttpListener)r.AsyncState; var ctx = l.EndGetContext(r); var req = ctx.Request; var resp = ctx.Response; var serializer = NewJsonSerializer(); Request request = null; resp.StatusCode = (int)HttpStatusCode.OK; using (var ins = new JsonTextReader(new StreamReader(req.InputStream))) { try { request = serializer.Deserialize <Request>(ins); } catch (JsonSerializationException e) { var buffer = Encoding.UTF8.GetBytes(e + ""); resp.StatusCode = (int)HttpStatusCode.BadRequest; resp.ContentLength64 = buffer.Length; resp.OutputStream.Write(buffer, 0, buffer.Length); } // ignore, bad request } var db = host.Database; var configOpt = new ConfigOpt(this.host.CustomConfig); if (request != null && (configOpt.UnlockDatabaseRequest || request.TriggerUnlock == "true") && !db.IsOpen) { host.MainWindow.Invoke((MethodInvoker) delegate { host.MainWindow.EnsureVisibleForegroundWindow(true, true); }); // UnlockDialog not already opened bool bNoDialogOpened = (KeePass.UI.GlobalWindowManager.WindowCount == 0); if (!db.IsOpen && bNoDialogOpened) { host.MainWindow.Invoke((MethodInvoker) delegate { host.MainWindow.OpenDatabase(host.MainWindow.DocumentManager.ActiveDocument.LockedIoc, null, false); }); } } if (request != null && db.IsOpen) { Response response = null; if (request != null) { response = ProcessRequest(request, resp); } resp.ContentType = "application/json"; var writer = new StringWriter(); if (response != null) { serializer.Serialize(writer, response); var buffer = Encoding.UTF8.GetBytes(writer.ToString()); resp.ContentLength64 = buffer.Length; resp.OutputStream.Write(buffer, 0, buffer.Length); } } else { resp.StatusCode = (int)HttpStatusCode.ServiceUnavailable; } var outs = resp.OutputStream; outs.Close(); resp.Close(); }
private IEnumerable<PwEntryDatabase> FindMatchingEntries(Request r, Aes aes) { string submithost = null; string realm = null; var listResult = new List<PwEntryDatabase>(); string formhost, searchHost; formhost = searchHost = GetHost(CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT)); if (r.SubmitUrl != null) { submithost = GetHost(CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT)); } if (r.Realm != null) realm = CryptoTransform(r.Realm, true, false, aes, CMode.DECRYPT); var origSearchHost = searchHost; var parms = MakeSearchParameters(); List<PwDatabase> listDatabases = new List<PwDatabase>(); 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) { searchHost = origSearchHost; //get all possible entries for given host-name while (listResult.Count == listCount && (origSearchHost == searchHost || searchHost.IndexOf(".") != -1)) { parms.SearchString = String.Format("^{0}$|/{0}/?", searchHost); var listEntries = new PwObjectList<PwEntry>(); db.RootGroup.SearchEntries(parms, listEntries); foreach (var le in listEntries) { listResult.Add(new PwEntryDatabase(le, db)); } searchHost = searchHost.Substring(searchHost.IndexOf(".") + 1); //searchHost contains no dot --> prevent possible infinite loop if (searchHost == origSearchHost) break; } listCount = listResult.Count; } Func<PwEntry, bool> filter = delegate(PwEntry e) { var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); var c = GetEntryConfig(e); if (c != null) { if (c.Allow.Contains(formhost) && (submithost == null || c.Allow.Contains(submithost))) return true; if (c.Deny.Contains(formhost) || (submithost != null && c.Deny.Contains(submithost))) return false; if (realm != null && c.Realm != realm) return false; } if (title.StartsWith("http://") || title.StartsWith("https://")) { var u = new Uri(title); if (formhost.Contains(u.Host)) return true; } if (entryUrl != null && entryUrl.StartsWith("http://") || entryUrl.StartsWith("https://")) { var u = new Uri(entryUrl); if (formhost.Contains(u.Host)) return true; } return formhost.Contains(title) || (entryUrl != null && formhost.Contains(entryUrl)); }; return from e in listResult where filter(e.entry) select e; }
private void GetLoginsHandler(Request r, Response resp, Aes aes) { if (!VerifyRequest(r, aes)) return; string submithost = null; var host = GetHost(CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT)); if (r.SubmitUrl != null) submithost = GetHost(CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT)); var items = FindMatchingEntries(r, aes); if (items.ToList().Count > 0) { Func<PwEntry, bool> filter = delegate(PwEntry e) { var c = GetEntryConfig(e); var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); if (c != null) { return title != host && entryUrl != host && !c.Allow.Contains(host) || (submithost != null && !c.Allow.Contains(submithost) && submithost != title && submithost != entryUrl); } return title != host && entryUrl != host || (submithost != null && title != submithost && entryUrl != submithost); }; 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 clicked = true; if (canShowBalloonTips()) { clicked = false; var wait = new ManualResetEvent(false); var delegated = false; EventHandler onclick = delegate { delegated = true; clicked = true; wait.Set(); }; EventHandler onclose = delegate { delegated = true; wait.Set(); }; ShowNotification(String.Format( "{0}: {1} is requesting access, click to allow or deny", r.Id, submithost != null ? submithost : host), onclick, onclose); wait.WaitOne(GetNotificationTime() + 5000); // give a little time to fade if (!delegated) resp.Error = "Notification bubble did not appear"; } if (clicked) { 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.Entries = needPrompting.ToList(); f.Host = submithost != null ? submithost : host; 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(host); if (submithost != null && submithost != host) set.Add(submithost); SetEntryConfig(e.entry, c); } } if (!f.Allowed) { items = items.Except(needPrompting); } }); } } else { items = items.Except(needPrompting); } } if (r.SortSelection == "true" || configOpt.SpecificMatchingOnly) { string sortHost = CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT); if (sortHost.EndsWith("/")) sortHost = sortHost.Substring(0, sortHost.Length - 1); string sortSubmiturl = CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT); if (sortSubmiturl == null) sortSubmiturl = String.Copy(sortHost); if (sortSubmiturl.EndsWith("/")) sortSubmiturl = sortSubmiturl.Substring(0, sortSubmiturl.Length - 1); if (!sortSubmiturl.Contains("://")) sortSubmiturl = "http://" + sortSubmiturl; if (!sortHost.Contains("://")) sortHost = "http://" + sortHost; string sortBaseSubmiturl = String.Copy(sortSubmiturl); if (sortSubmiturl.LastIndexOf("/") > 7) { Uri sortBaseSubmithostURI = new Uri(sortSubmiturl); sortBaseSubmiturl = String.Format("{0}{1}{2}{3}", sortBaseSubmithostURI.Scheme, Uri.SchemeDelimiter, sortBaseSubmithostURI.Authority, sortBaseSubmithostURI.AbsolutePath.Substring(0, sortBaseSubmithostURI.AbsolutePath.LastIndexOf("/"))); } sortSubmiturl = sortSubmiturl.ToLower(); sortHost = sortHost.ToLower(); sortBaseSubmiturl = sortBaseSubmiturl.ToLower(); foreach (var entryDatabase in items) { string entryUrl = String.Copy(entryDatabase.entry.Strings.ReadSafe(PwDefs.UrlField)); if (entryUrl.EndsWith("/")) entryUrl = entryUrl.Substring(0, entryUrl.Length - 1); entryUrl = entryUrl.ToLower(); if (!entryUrl.Contains("://")) entryUrl = "http://" + entryUrl; string baseEntryUrl = String.Copy(entryUrl); if (baseEntryUrl.LastIndexOf("/") > 7) { Uri baseEntryUrlURI = new Uri(entryUrl); baseEntryUrl = String.Format("{0}{1}{2}{3}", baseEntryUrlURI.Scheme, Uri.SchemeDelimiter, baseEntryUrlURI.Authority, baseEntryUrlURI.AbsolutePath.Substring(0, baseEntryUrlURI.AbsolutePath.LastIndexOf("/"))); } if (sortSubmiturl == entryUrl) entryDatabase.entry.UsageCount = 90; else if (sortSubmiturl.StartsWith(entryUrl) && sortHost != entryUrl && sortBaseSubmiturl != entryUrl) entryDatabase.entry.UsageCount = 80; else if (sortSubmiturl.StartsWith(baseEntryUrl) && sortHost != baseEntryUrl && sortBaseSubmiturl != baseEntryUrl) entryDatabase.entry.UsageCount = 70; else if (sortHost == entryUrl) entryDatabase.entry.UsageCount = 50; else if (sortBaseSubmiturl == entryUrl) entryDatabase.entry.UsageCount = 40; else if (entryUrl.StartsWith(sortSubmiturl)) entryDatabase.entry.UsageCount = 30; else if (entryUrl.StartsWith(sortBaseSubmiturl) && sortBaseSubmiturl != sortHost) entryDatabase.entry.UsageCount = 25; else if (sortSubmiturl.StartsWith(entryUrl)) entryDatabase.entry.UsageCount = 20; else if (sortSubmiturl.StartsWith(baseEntryUrl)) entryDatabase.entry.UsageCount = 15; else if (entryUrl.StartsWith(sortHost)) entryDatabase.entry.UsageCount = 10; else if (sortHost.StartsWith(entryUrl)) entryDatabase.entry.UsageCount = 5; else entryDatabase.entry.UsageCount = 1; } var items2 = from e in items orderby e.entry.UsageCount descending select e; items = items2; } if (configOpt.SpecificMatchingOnly) { ulong highestCount = 0; foreach (var entryDatabase in items) { if (highestCount == 0) { highestCount = entryDatabase.entry.UsageCount; } if (entryDatabase.entry.UsageCount == highestCount) { var name = entryDatabase.entry.Strings.ReadSafe(PwDefs.TitleField); var loginpass = GetUserPass(entryDatabase); var login = loginpass[0]; var passwd = loginpass[1]; var uuid = entryDatabase.entry.Uuid.ToHexString(); var e = new ResponseEntry(name, login, passwd, uuid); resp.Entries.Add(e); } } } else { foreach (var entryDatabase in items) { var name = entryDatabase.entry.Strings.ReadSafe(PwDefs.TitleField); var loginpass = GetUserPass(entryDatabase); var login = loginpass[0]; var passwd = loginpass[1]; var uuid = entryDatabase.entry.Uuid.ToHexString(); var e = new ResponseEntry(name, login, passwd, uuid); resp.Entries.Add(e); } } if (items.ToList().Count > 0) { var names = (from e in resp.Entries select e.Name).Distinct<string>(); var n = String.Join("\n ", names.ToArray<string>()); 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); } resp.Count = resp.Entries.Count; } else { resp.Success = true; resp.Id = r.Id; SetResponseVerifier(resp, aes); } }
private bool UpdateEntry(PwUuid uuid, string username, string password, string formHost, string requestId) { PwEntry entry = null; var configOpt = new ConfigOpt(this.host.CustomConfig); if (configOpt.SearchInAllOpenedDatabases) { foreach (PwDocument doc in host.MainWindow.DocumentManager.Documents) { if (doc.Database.IsOpen) { entry = doc.Database.RootGroup.FindEntry(uuid, true); if (entry != null) { break; } } } } else { entry = host.Database.RootGroup.FindEntry(uuid, true); } if (entry == null) { return false; } string[] up = GetUserPass(entry); var u = up[0]; var p = up[1]; if (u != username || p != password) { bool allowUpdate = configOpt.AlwaysAllowUpdates; if (!allowUpdate) { host.MainWindow.Activate(); DialogResult result; if (host.MainWindow.IsTrayed()) { result = MessageBox.Show( String.Format("Do you want to update the information in {0} - {1}?", formHost, u), "Update Entry", MessageBoxButtons.YesNo, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } else { result = MessageBox.Show( host.MainWindow, String.Format("Do you want to update the information in {0} - {1}?", formHost, u), "Update Entry", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); } if (result == DialogResult.Yes) { allowUpdate = true; } } if (allowUpdate) { PwObjectList<PwEntry> m_vHistory = entry.History.CloneDeep(); entry.History = m_vHistory; entry.CreateBackup(null); entry.Strings.Set(PwDefs.UserNameField, new ProtectedString(false, username)); entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(true, password)); entry.Touch(true, false); UpdateUI(entry.ParentGroup); return true; } } return false; }
private void GetLoginsHandler(Request r, Response resp, Aes aes) { if (!VerifyRequest(r, aes)) return; string submithost = null; var host = GetHost(CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT)); if (r.SubmitUrl != null) submithost = GetHost(CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT)); var items = FindMatchingEntries(r, aes); if (items.ToList().Count > 0) { Func<PwEntry, bool> filter = delegate(PwEntry e) { var c = GetEntryConfig(e); var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); if (c != null) { return title != host && entryUrl != host && !c.Allow.Contains(host) || (submithost != null && !c.Allow.Contains(submithost) && submithost != title && submithost != entryUrl); } return title != host && entryUrl != host || (submithost != null && title != submithost && entryUrl != submithost); }; 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.Entries = needPrompting.ToList(); f.Host = submithost != null ? submithost : host; 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(host); if (submithost != null && submithost != host) set.Add(submithost); SetEntryConfig(e.entry, c); } } if (!f.Allowed) { items = items.Except(needPrompting); } }); } } string compareToUrl = null; if (r.SubmitUrl != null) { compareToUrl = CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT); } if(String.IsNullOrEmpty(compareToUrl)) compareToUrl = CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT); compareToUrl = compareToUrl.ToLower(); foreach (var entryDatabase in items) { string entryUrl = String.Copy(entryDatabase.entry.Strings.ReadSafe(PwDefs.UrlField)); if (String.IsNullOrEmpty(entryUrl)) entryUrl = entryDatabase.entry.Strings.ReadSafe(PwDefs.TitleField); entryUrl = entryUrl.ToLower(); entryDatabase.entry.UsageCount = (ulong)LevenshteinDistance(compareToUrl, entryUrl); } var itemsList = items.ToList(); if (configOpt.SpecificMatchingOnly) { itemsList = (from e in itemsList orderby e.entry.UsageCount ascending select e).ToList(); ulong lowestDistance = itemsList.Count > 0 ? itemsList[0].entry.UsageCount : 0; 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<string>(); var n = String.Join("\n ", names.ToArray<string>()); 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; } else { resp.Success = true; resp.Id = r.Id; SetResponseVerifier(resp, aes); } }
private bool CreateEntry(string username, string password, string urlHost, string url, Request r, Aes aes) { string realm = null; if (r.Realm != null) { realm = CryptoTransform(r.Realm, true, false, aes, CMode.DECRYPT); } var configOpt = new ConfigOpt(this.host.CustomConfig); var root = host.Database.RootGroup; var loc = root; if (!String.IsNullOrEmpty(configOpt.PleasantPasswordFolder)) { var priv = root.FindCreateGroup("Private Folders", false); loc = priv.FindCreateGroup(configOpt.PleasantPasswordFolder, false); } var group = loc.FindCreateGroup(KEEPASSHTTP_GROUP_NAME, false); if (group == null) { group = new PwGroup(true, true, KEEPASSHTTP_GROUP_NAME, PwIcon.WorldComputer); loc.AddGroup(group, true); UpdateUI(null); } string submithost = null; if (r.SubmitUrl != null) { submithost = GetHost(CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT)); } string baseUrl = url; // index bigger than https:// <-- this slash if (baseUrl.LastIndexOf("/") > 9) { baseUrl = baseUrl.Substring(0, baseUrl.LastIndexOf("/") + 1); } PwEntry entry = new PwEntry(true, true); entry.Strings.Set(PwDefs.TitleField, new ProtectedString(false, urlHost)); entry.Strings.Set(PwDefs.UserNameField, new ProtectedString(false, username)); entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(true, password)); entry.Strings.Set(PwDefs.UrlField, new ProtectedString(true, baseUrl)); if ((submithost != null && urlHost != submithost) || realm != null) { var config = new KeePassHttpEntryConfig(); if (submithost != null) { config.Allow.Add(submithost); } if (realm != null) { config.Realm = realm; } var serializer = NewJsonSerializer(); var writer = new StringWriter(); serializer.Serialize(writer, config); entry.Strings.Set(KEEPASSHTTP_NAME, new ProtectedString(false, writer.ToString())); } group.AddEntry(entry, true); UpdateUI(group); return(true); }
private void GetLoginsHandler(Request r, Response resp, Aes aes) { if (!VerifyRequest(r, aes)) return; string submithost = null; var host = GetHost(CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT)); if (r.SubmitUrl != null) submithost = GetHost(CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT)); var items = FindMatchingEntries(r, aes); if (items.ToList().Count > 0) { Func<PwEntry, bool> filter = delegate(PwEntry e) { var c = GetEntryConfig(e); var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); if (c != null) { return title != host && entryUrl != host && !c.Allow.Contains(host) || (submithost != null && !c.Allow.Contains(submithost) && submithost != title && submithost != entryUrl); } return title != host && entryUrl != host || (submithost != null && title != submithost && entryUrl != submithost); }; var config = GetConfigEntry(true); var autoAllowS = config.Strings.ReadSafe("Auto Allow"); var autoAllow = autoAllowS != null && autoAllowS.Trim() != ""; var needPrompting = from e in items where filter(e) select e; if (needPrompting.ToList().Count > 0 && !autoAllow) { var wait = new ManualResetEvent(false); var clicked = false; var delegated = false; EventHandler onclick = delegate { delegated = true; clicked = true; wait.Set(); }; EventHandler onclose = delegate { delegated = true; wait.Set(); }; ShowNotification(String.Format( "{0}: {1} is requesting access, click to allow or deny", r.Id, submithost != null ? submithost : host), onclick, onclose); wait.WaitOne(GetNotificationTime() + 5000); // give a little time to fade if (!delegated) resp.Error = "Notification bubble did not appear"; if (clicked) { var win = this.host.MainWindow; using (var f = new AccessControlForm()) { win.Invoke((MethodInvoker)delegate { f.Icon = win.Icon; f.Plugin = this; f.Entries = needPrompting.ToList(); f.Host = submithost != null ? submithost : host; f.Load += delegate { f.Activate(); }; f.ShowDialog(win); if (f.Remember && (f.Allowed || f.Denied)) { foreach (var e in needPrompting) { var c = GetEntryConfig(e); if (c == null) c = new KeePassHttpEntryConfig(); var set = f.Allowed ? c.Allow : c.Deny; set.Add(host); if (submithost != null && submithost != host) set.Add(submithost); SetEntryConfig(e, c); } } if (!f.Allowed) items = items.Except(needPrompting); }); } } else { items = items.Except(needPrompting); } } foreach (var entry in items) { var name = entry.Strings.ReadSafe(PwDefs.TitleField); var loginpass = GetUserPass(entry); var login = loginpass[0]; var passwd = loginpass[1]; var uuid = entry.Uuid.ToHexString(); var e = new ResponseEntry(name, login, passwd, uuid); resp.Entries.Add(e); } if (items.ToList().Count > 0) { var names = (from e in resp.Entries select e.Name).Distinct<string>(); var n = String.Join("\n ", names.ToArray<string>()); var configOpt = new ConfigOpt(this.host.CustomConfig); 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); } } }
public override bool Initialize(IPluginHost host) { var httpSupported = HttpListener.IsSupported; this.host = host; var optionsMenu = new ToolStripMenuItem("KeePassHttp Options..."); optionsMenu.Click += OnOptions_Click; optionsMenu.Image = KeePassHttp.Properties.Resources.earth_lock; //optionsMenu.Image = global::KeePass.Properties.Resources.B16x16_File_Close; this.host.MainWindow.ToolsMenu.DropDownItems.Add(optionsMenu); if (httpSupported) { try { handlers.Add(Request.TEST_ASSOCIATE, TestAssociateHandler); handlers.Add(Request.ASSOCIATE, AssociateHandler); handlers.Add(Request.GET_LOGINS, GetLoginsHandler); handlers.Add(Request.GET_LOGINS_COUNT, GetLoginsCountHandler); handlers.Add(Request.GET_ALL_LOGINS, GetAllLoginsHandler); handlers.Add(Request.SET_LOGIN, SetLoginHandler); handlers.Add(Request.GENERATE_PASSWORD, GeneratePassword); listener = new HttpListener(); var configOpt = new ConfigOpt(this.host.CustomConfig); listener.Prefixes.Add(HTTP_PREFIX + configOpt.ListenerPort.ToString() + "/"); //listener.Prefixes.Add(HTTPS_PREFIX + HTTPS_PORT + "/"); listener.Start(); httpThread = new Thread(new ThreadStart(Run)); httpThread.Start(); } catch (HttpListenerException e) { MessageBox.Show(host.MainWindow, "Unable to start HttpListener!\nDo you really have only one installation of KeePassHttp in your KeePass-directory?\n\n" + e, "Unable to start HttpListener", MessageBoxButtons.OK, MessageBoxIcon.Error ); } } else { MessageBox.Show(host.MainWindow, "The .NET HttpListener is not supported on your OS", ".NET HttpListener not supported", MessageBoxButtons.OK, MessageBoxIcon.Error ); } return httpSupported; }
private bool UpdateEntry(PwUuid uuid, string username, string password, string formHost, string requestId, string groupName, string name) { PwEntry entry = null; var configOpt = new ConfigOpt(this.host.CustomConfig); if (configOpt.SearchInAllOpenedDatabases) { foreach (PwDocument doc in host.MainWindow.DocumentManager.Documents) { if (doc.Database.IsOpen) { entry = doc.Database.RootGroup.FindEntry(uuid, true); if (entry != null) { break; } } } } else { entry = host.Database.RootGroup.FindEntry(uuid, true); } if (entry == null) { return(false); } string[] up = GetUserPass(entry); var u = up[0]; var p = up[1]; var t = up[2]; var currentGroup = entry.ParentGroup.GetFullPath("/", true); // prepend the passed group w/ the root group name so it matches the GetFullPath var fullGroupName = host.Database.RootGroup.Name + "/" + groupName; if (u != username || p != password || (groupName != null && currentGroup != fullGroupName) || (name != null && t != name)) { bool allowUpdate = configOpt.AlwaysAllowUpdates; if (!allowUpdate) { host.MainWindow.Activate(); DialogResult result; if (host.MainWindow.IsTrayed()) { result = MessageBox.Show( String.Format("Do you want to update the information in {0} - {1}?", formHost, u), "Update Entry", MessageBoxButtons.YesNo, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } else { result = MessageBox.Show( host.MainWindow, String.Format("Do you want to update the information in {0} - {1}?", formHost, u), "Update Entry", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); } if (result == DialogResult.Yes) { allowUpdate = true; } } if (allowUpdate) { if (groupName != null) { PwGroup newGroup; if (groupName == "/") { newGroup = host.Database.RootGroup; } else { newGroup = host.Database.RootGroup.FindCreateSubTree(groupName, KEEPASSHTTP_GROUP_SEPERATOR); } if (entry.ParentGroup != newGroup) { var oldGroup = entry.ParentGroup; newGroup.AddEntry(entry, true); oldGroup.Entries.Remove(entry); } } PwObjectList <PwEntry> m_vHistory = entry.History.CloneDeep(); entry.History = m_vHistory; entry.CreateBackup(null); if (name != null) { entry.Strings.Set(PwDefs.TitleField, new ProtectedString(false, name)); } entry.Strings.Set(PwDefs.UserNameField, new ProtectedString(false, username)); entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(true, password)); entry.Touch(true, false); UpdateUI(entry.ParentGroup); return(true); } } return(false); }
private ResponseEntry PrepareElementForResponseEntries(ConfigOpt configOpt, PwEntryDatabase entryDatabase) { var name = entryDatabase.entry.Strings.ReadSafe(PwDefs.TitleField); var loginpass = GetUserPass(entryDatabase); var login = loginpass[0]; var passwd = loginpass[1]; var uuid = entryDatabase.entry.Uuid.ToHexString(); List<ResponseStringField> fields = null; if (configOpt.ReturnStringFields) { fields = new List<ResponseStringField>(); foreach (var sf in entryDatabase.entry.Strings) { 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 { fields.Add(new ResponseStringField(sf.Key, sfValue)); } } if (fields.Count > 0) { var fields2 = from e2 in fields orderby e2.Key ascending select e2; fields = fields2.ToList<ResponseStringField>(); } else { fields = null; } } return new ResponseEntry(name, login, passwd, uuid, fields); }
private IEnumerable<PwEntryDatabase> FindMatchingEntriesLikeSearchbox(Request r, Aes aes) { string searchString = null; string realm = null; var listResult = new List<PwEntryDatabase>(); 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<PwDatabase> listDatabases = new List<PwDatabase>(); 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<PwEntry>(); db.RootGroup.SearchEntries(parms, listEntries); foreach (var le in listEntries) { listResult.Add(new PwEntryDatabase(le, db)); } } return listResult; }
public OptionsForm(ConfigOpt config) { _config = config; InitializeComponent(); }
private void SetLoginHandler(Request r, Response resp, Aes aes) { if (!VerifyRequest(r, aes)) return; string submithost = null; PwUuid uuid = null; string username, password, url; string realm = null; url = CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT); var formhost = GetHost(url); if (r.SubmitUrl != null) submithost = GetHost(CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT)); if (r.Realm != null) realm = CryptoTransform(r.Realm, true, false, aes, CMode.DECRYPT); username = CryptoTransform(r.Login, true, false, aes, CMode.DECRYPT); password = CryptoTransform(r.Password, true, false, aes, CMode.DECRYPT); if (r.Uuid != null) { uuid = new PwUuid(MemUtil.HexStringToByteArray( CryptoTransform(r.Uuid, true, false, aes, CMode.DECRYPT))); } if (uuid != null) { // modify existing entry PwEntry entry = host.Database.RootGroup.FindEntry(uuid, true); string[] up = GetUserPass(entry); var u = up[0]; var p = up[1]; var configOpt = new ConfigOpt(this.host.CustomConfig); if (u != username || p != password) { bool allowUpdate = configOpt.AlwaysAllowUpdates; if (!allowUpdate) { if (canShowBalloonTips()) { ShowNotification(String.Format( "{0}: You have an entry change prompt waiting, click to activate", r.Id), (s, e) => host.MainWindow.Activate()); } DialogResult result; if (host.MainWindow.IsTrayed()) { result = MessageBox.Show( String.Format("Do you want to update the information in {0} - {1}?", formhost, u), "Update Entry", MessageBoxButtons.YesNo, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } else { result = MessageBox.Show( host.MainWindow, String.Format("Do you want to update the information in {0} - {1}?", formhost, u), "Update Entry", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); } if (result == DialogResult.Yes) { allowUpdate = true; } } if (allowUpdate) { PwObjectList<PwEntry> m_vHistory = entry.History.CloneDeep(); entry.History = m_vHistory; entry.CreateBackup(null); entry.Strings.Set(PwDefs.UserNameField, new ProtectedString(false, username)); entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(true, password)); entry.Touch(true, false); UpdateUI(entry.ParentGroup); } } } else { // creating new entry var root = host.Database.RootGroup; var group = root.FindCreateGroup(KEEPASSHTTP_GROUP_NAME, false); if (group == null) { group = new PwGroup(true, true, KEEPASSHTTP_GROUP_NAME, PwIcon.WorldComputer); root.AddGroup(group, true); UpdateUI(null); } PwEntry entry = new PwEntry(true, true); entry.Strings.Set(PwDefs.TitleField, new ProtectedString(false, formhost)); entry.Strings.Set(PwDefs.UserNameField, new ProtectedString(false, username)); entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(true, password)); entry.Strings.Set(PwDefs.UrlField, new ProtectedString(true, url)); if ((submithost != null && formhost != submithost) || realm != null) { var config = new KeePassHttpEntryConfig(); if (submithost != null) config.Allow.Add(submithost); if (realm != null) config.Realm = realm; var serializer = NewJsonSerializer(); var writer = new StringWriter(); serializer.Serialize(writer, config); entry.Strings.Set(KEEPASSHTTP_NAME, new ProtectedString(false, writer.ToString())); } group.AddEntry(entry, true); UpdateUI(group); } resp.Success = true; resp.Id = r.Id; SetResponseVerifier(resp, aes); }
private bool CreateEntry(string username, string password, string urlHost, string url, Request r, Aes aes) { string realm = null; if (r.Realm != null) realm = CryptoTransform(r.Realm, true, false, aes, CMode.DECRYPT); var root = host.Database.RootGroup; // Get stored RootGroup from config if any var configOpt = new ConfigOpt(this.host.CustomConfig); if (configOpt.RootGroup != "") { var GroupUuid = new PwUuid(StringToByteArray(configOpt.RootGroupUuid)); root = root.FindGroup(GroupUuid, true); } var group = root.FindCreateGroup(KEEPASSHTTP_GROUP_NAME, false); if (group == null) { group = new PwGroup(true, true, KEEPASSHTTP_GROUP_NAME, PwIcon.WorldComputer); root.AddGroup(group, true); UpdateUI(null); } string submithost = null; if (r.SubmitUrl != null) submithost = GetHost(CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT)); string baseUrl = url; // index bigger than https:// <-- this slash if (baseUrl.LastIndexOf("/") > 9) { baseUrl = baseUrl.Substring(0, baseUrl.LastIndexOf("/") + 1); } PwEntry entry = new PwEntry(true, true); entry.Strings.Set(PwDefs.TitleField, new ProtectedString(false, urlHost)); entry.Strings.Set(PwDefs.UserNameField, new ProtectedString(false, username)); entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(true, password)); entry.Strings.Set(PwDefs.UrlField, new ProtectedString(true, baseUrl)); if ((submithost != null && urlHost != submithost) || realm != null) { var config = new KeePassHttpEntryConfig(); if (submithost != null) config.Allow.Add(submithost); if (realm != null) config.Realm = realm; var serializer = NewJsonSerializer(); var writer = new StringWriter(); serializer.Serialize(writer, config); entry.Strings.Set(KEEPASSHTTP_NAME, new ProtectedString(false, writer.ToString())); } group.AddEntry(entry, true); UpdateUI(group); return true; }
private void _RequestHandler(IAsyncResult r) { if (stopped) return; var l = (HttpListener)r.AsyncState; var ctx = l.EndGetContext(r); var req = ctx.Request; var resp = ctx.Response; var db = host.Database; var configOpt = new ConfigOpt(this.host.CustomConfig); if (configOpt.UnlockDatabaseRequest && !db.IsOpen) { host.MainWindow.Invoke((MethodInvoker)delegate { host.MainWindow.EnsureVisibleForegroundWindow(true, true); }); if (!db.IsOpen) { host.MainWindow.Invoke((MethodInvoker)delegate { host.MainWindow.OpenDatabase(host.MainWindow.DocumentManager.ActiveDocument.LockedIoc, null, false); }); } } if (db.IsOpen) { var serializer = NewJsonSerializer(); Request request = null; resp.StatusCode = (int)HttpStatusCode.OK; using (var ins = new JsonTextReader(new StreamReader(req.InputStream))) { try { request = serializer.Deserialize<Request>(ins); } catch (JsonSerializationException e) { var buffer = Encoding.UTF8.GetBytes(e + ""); resp.StatusCode = (int)HttpStatusCode.BadRequest; resp.ContentLength64 = buffer.Length; resp.OutputStream.Write(buffer, 0, buffer.Length); } // ignore, bad request } Response response = null; if (request != null) response = ProcessRequest(request, resp); resp.ContentType = "application/json"; var writer = new StringWriter(); if (response != null) { serializer.Serialize(writer, response); var buffer = Encoding.UTF8.GetBytes(writer.ToString()); resp.ContentLength64 = buffer.Length; resp.OutputStream.Write(buffer, 0, buffer.Length); } } else { resp.StatusCode = (int)HttpStatusCode.ServiceUnavailable; } var outs = resp.OutputStream; outs.Close(); resp.Close(); }
private void GetAllLoginsHandler(Request r, Response resp, Aes aes) { if (!VerifyRequest(r, aes)) return; var list = new PwObjectList<PwEntry>(); var root = host.Database.RootGroup; // Get stored RootGroup from config if any var configOpt = new ConfigOpt(this.host.CustomConfig); if (configOpt.RootGroup != "") { var GroupUuid = new PwUuid(GetBytes(configOpt.RootGroupUuid)); root = root.FindGroup(GroupUuid, true); } var parms = MakeSearchParameters(); parms.SearchString = @"^[A-Za-z0-9:/-]+\.[A-Za-z0-9:/-]+$"; // match anything looking like a domain or url root.SearchEntries(parms, list); foreach (var entry in list) { var name = entry.Strings.ReadSafe(PwDefs.TitleField); var login = GetUserPass(entry)[0]; var uuid = entry.Uuid.ToHexString(); var e = new ResponseEntry(name, login, null, uuid, null); resp.Entries.Add(e); } 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); } }
private void GetLoginsHandler(Request r, Response resp, Aes aes) { if (!VerifyRequest(r, aes)) { return; } string submithost = null; var host = GetHost(CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT)); if (r.SubmitUrl != null) { submithost = GetHost(CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT)); } var items = FindMatchingEntries(r, aes); if (items.ToList().Count > 0) { Func <PwEntry, bool> filter = delegate(PwEntry e) { var c = GetEntryConfig(e); var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); if (c != null) { return(title != host && entryUrl != host && !c.Allow.Contains(host) || (submithost != null && !c.Allow.Contains(submithost) && submithost != title && submithost != entryUrl)); } return(title != host && entryUrl != host || (submithost != null && title != submithost && entryUrl != submithost)); }; 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.Entries = needPrompting.ToList(); f.Host = submithost != null ? submithost : host; 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(host); if (submithost != null && submithost != host) { set.Add(submithost); } SetEntryConfig(e.entry, c); } } if (!f.Allowed) { items = items.Except(needPrompting); } }); } } //if (r.SortSelection == "true" || configOpt.SpecificMatchingOnly) //{ string sortHost = CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT); if (sortHost.EndsWith("/")) { sortHost = sortHost.Substring(0, sortHost.Length - 1); } string sortSubmiturl = null; if (r.SubmitUrl != null) { sortSubmiturl = CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT); } if (sortSubmiturl == null) { sortSubmiturl = String.Copy(sortHost); } if (sortSubmiturl.EndsWith("/")) { sortSubmiturl = sortSubmiturl.Substring(0, sortSubmiturl.Length - 1); } if (!sortSubmiturl.Contains("://")) { sortSubmiturl = "http://" + sortSubmiturl; } if (!sortHost.Contains("://")) { sortHost = "http://" + sortHost; } string sortBaseSubmiturl = String.Copy(sortSubmiturl); if (sortSubmiturl.LastIndexOf("/") > 7) { Uri sortBaseSubmithostURI = new Uri(sortSubmiturl); sortBaseSubmiturl = String.Format("{0}{1}{2}{3}", sortBaseSubmithostURI.Scheme, Uri.SchemeDelimiter, sortBaseSubmithostURI.Authority, sortBaseSubmithostURI.AbsolutePath.Substring(0, sortBaseSubmithostURI.AbsolutePath.LastIndexOf("/")) ); } sortSubmiturl = sortSubmiturl.ToLower(); sortHost = sortHost.ToLower(); sortBaseSubmiturl = sortBaseSubmiturl.ToLower(); foreach (var entryDatabase in items) { string entryUrl = String.Copy(entryDatabase.entry.Strings.ReadSafe(PwDefs.UrlField)); if (entryUrl.EndsWith("/")) { entryUrl = entryUrl.Substring(0, entryUrl.Length - 1); } entryUrl = entryUrl.ToLower(); if (!entryUrl.Contains("://")) { entryUrl = "http://" + entryUrl; } string baseEntryUrl = String.Copy(entryUrl); if (baseEntryUrl.LastIndexOf("/") > 7) { Uri baseEntryUrlURI = new Uri(entryUrl); baseEntryUrl = String.Format("{0}{1}{2}{3}", baseEntryUrlURI.Scheme, Uri.SchemeDelimiter, baseEntryUrlURI.Authority, baseEntryUrlURI.AbsolutePath.Substring(0, baseEntryUrlURI.AbsolutePath.LastIndexOf("/"))); } if (sortSubmiturl == entryUrl) { entryDatabase.entry.UsageCount = 90; } else if (sortSubmiturl.StartsWith(entryUrl) && sortHost != entryUrl && sortBaseSubmiturl != entryUrl) { entryDatabase.entry.UsageCount = 80; } else if (sortSubmiturl.StartsWith(baseEntryUrl) && sortHost != baseEntryUrl && sortBaseSubmiturl != baseEntryUrl) { entryDatabase.entry.UsageCount = 70; } else if (sortHost == entryUrl) { entryDatabase.entry.UsageCount = 50; } else if (sortBaseSubmiturl == entryUrl) { entryDatabase.entry.UsageCount = 40; } else if (entryUrl.StartsWith(sortSubmiturl)) { entryDatabase.entry.UsageCount = 30; } else if (entryUrl.StartsWith(sortBaseSubmiturl) && sortBaseSubmiturl != sortHost) { entryDatabase.entry.UsageCount = 25; } else if (sortSubmiturl.StartsWith(entryUrl)) { entryDatabase.entry.UsageCount = 20; } else if (sortSubmiturl.StartsWith(baseEntryUrl)) { entryDatabase.entry.UsageCount = 15; } else if (entryUrl.StartsWith(sortHost)) { entryDatabase.entry.UsageCount = 10; } else if (sortHost.StartsWith(entryUrl)) { entryDatabase.entry.UsageCount = 5; } else { entryDatabase.entry.UsageCount = 1; } } //} var itemsList = items.ToList(); if (configOpt.SpecificMatchingOnly) { ulong highestCount = 0; foreach (var entryDatabase in itemsList.ToList()) { if (highestCount == 0) { highestCount = entryDatabase.entry.UsageCount; } if (entryDatabase.entry.UsageCount != highestCount) { itemsList.Remove(entryDatabase); } } } if (configOpt.SortResultByUsername) { var items2 = from e in itemsList orderby e.entry.UsageCount descending, GetUserPass(e)[0] ascending select e; itemsList = items2.ToList(); } else { var items2 = from e in itemsList orderby e.entry.UsageCount descending, 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 <string>(); var n = String.Join("\n ", names.ToArray <string>()); 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; } else { resp.Success = true; resp.Id = r.Id; SetResponseVerifier(resp, aes); } }
private IEnumerable <PwEntryDatabase> FindMatchingEntries(Request r, Aes aes) { string submitHost = null; string realm = null; var listResult = new List <PwEntryDatabase>(); var url = CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT); string formHost, searchHost, submitUrl; formHost = searchHost = GetHost(url); string hostScheme = GetScheme(url); if (r.SubmitUrl != null) { submitUrl = CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT); submitHost = GetHost(submitUrl); } else { submitUrl = url; } if (r.Realm != null) { realm = CryptoTransform(r.Realm, true, false, aes, CMode.DECRYPT); } var origSearchHost = searchHost; var parms = MakeSearchParameters(); List <PwDatabase> listDatabases = new List <PwDatabase>(); 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 = ".*"; var listEntries = new PwObjectList <PwEntry>(); db.RootGroup.SearchEntries(parms, listEntries); foreach (var le in listEntries) { listResult.Add(new PwEntryDatabase(le, db)); } listCount = listResult.Count; } searchHost = origSearchHost; List <string> hostNameRegExps = new List <string>(); do { hostNameRegExps.Add(String.Format("^{0}$|/{0}/?", searchHost)); searchHost = searchHost.Substring(searchHost.IndexOf(".") + 1); } while (searchHost.IndexOf(".") != -1); Func <PwEntry, bool> filter = delegate(PwEntry e) { var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); var c = GetEntryConfig(e); if (c != null && c.RegExp != null) { try { return(Regex.IsMatch(submitUrl, c.RegExp)); } catch (Exception) { //ignore invalid pattern } } else { bool found = false; foreach (string hostNameRegExp in hostNameRegExps) { if (Regex.IsMatch(e.Strings.ReadSafe("URL"), hostNameRegExp) || Regex.IsMatch(e.Strings.ReadSafe("Title"), hostNameRegExp) || Regex.IsMatch(e.Strings.ReadSafe("Notes"), hostNameRegExp)) { found = true; break; } } if (!found) { return(false); } } if (c != null) { if (c.Allow.Contains(formHost) && (submitHost == null || c.Allow.Contains(submitHost))) { return(true); } if (c.Deny.Contains(formHost) || (submitHost != null && c.Deny.Contains(submitHost))) { return(false); } if (realm != null && c.Realm != realm) { return(false); } } if (entryUrl != null && (entryUrl.StartsWith("http://") || entryUrl.StartsWith("https://") || title.StartsWith("ftp://") || title.StartsWith("sftp://"))) { var uHost = GetHost(entryUrl); if (formHost.EndsWith(uHost)) { return(true); } } if (title.StartsWith("http://") || title.StartsWith("https://") || title.StartsWith("ftp://") || title.StartsWith("sftp://")) { var uHost = GetHost(title); if (formHost.EndsWith(uHost)) { return(true); } } return(formHost.Contains(title) || (entryUrl != null && entryUrl != "" && formHost.Contains(entryUrl))); }; Func <PwEntry, bool> filterSchemes = delegate(PwEntry e) { var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); if (entryUrl != null) { var entryScheme = GetScheme(entryUrl); if (entryScheme == hostScheme) { return(true); } } var titleScheme = GetScheme(title); if (titleScheme == hostScheme) { return(true); } return(false); }; var result = from e in listResult where filter(e.entry) select e; if (configOpt.MatchSchemes) { result = from e in result where filterSchemes(e.entry) select e; } Func <PwEntry, bool> hideExpired = delegate(PwEntry e) { DateTime dtNow = DateTime.UtcNow; if (e.Expires && (e.ExpiryTime <= dtNow)) { return(false); } return(true); }; if (configOpt.HideExpired) { result = from e in result where hideExpired(e.entry) select e; } return(result); }
private IEnumerable <PwEntryDatabase> FindMatchingEntries(Request r, Aes aes) { string submitHost = null; string realm = null; var listResult = new List <PwEntryDatabase>(); var url = CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT); string formHost, searchHost; formHost = searchHost = GetHost(url); string hostScheme = GetScheme(url); if (r.SubmitUrl != null) { submitHost = GetHost(CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT)); } if (r.Realm != null) { realm = CryptoTransform(r.Realm, true, false, aes, CMode.DECRYPT); } var origSearchHost = searchHost; var parms = MakeSearchParameters(); List <PwDatabase> listDatabases = new List <PwDatabase>(); 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) { searchHost = origSearchHost; //get all possible entries for given host-name while (listResult.Count == listCount && (origSearchHost == searchHost || searchHost.IndexOf(".") != -1)) { parms.SearchString = String.Format("^{0}$|/{0}/?", searchHost); var listEntries = new PwObjectList <PwEntry>(); db.RootGroup.SearchEntries(parms, listEntries); foreach (var le in listEntries) { listResult.Add(new PwEntryDatabase(le, db)); } searchHost = searchHost.Substring(searchHost.IndexOf(".") + 1); //searchHost contains no dot --> prevent possible infinite loop if (searchHost == origSearchHost) { break; } } listCount = listResult.Count; } Func <PwEntry, bool> filter = delegate(PwEntry e) { var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); var c = GetEntryConfig(e); if (c != null) { if (c.Allow.Contains(formHost) && (submitHost == null || c.Allow.Contains(submitHost))) { return(true); } if (c.Deny.Contains(formHost) || (submitHost != null && c.Deny.Contains(submitHost))) { return(false); } if (realm != null && c.Realm != realm) { return(false); } } if (entryUrl != null && (entryUrl.StartsWith("http://") || entryUrl.StartsWith("https://") || title.StartsWith("ftp://") || title.StartsWith("sftp://"))) { var uHost = GetHost(entryUrl); if (formHost.EndsWith(uHost)) { return(true); } } if (title.StartsWith("http://") || title.StartsWith("https://") || title.StartsWith("ftp://") || title.StartsWith("sftp://")) { var uHost = GetHost(title); if (formHost.EndsWith(uHost)) { return(true); } } return(formHost.Contains(title) || (entryUrl != null && formHost.Contains(entryUrl))); }; Func <PwEntry, bool> filterSchemes = delegate(PwEntry e) { var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); if (entryUrl != null) { var entryScheme = GetScheme(entryUrl); if (entryScheme == hostScheme) { return(true); } } var titleScheme = GetScheme(title); if (titleScheme == hostScheme) { return(true); } return(false); }; var result = from e in listResult where filter(e.entry) select e; if (configOpt.MatchSchemes) { result = from e in result where filterSchemes(e.entry) select e; } Func <PwEntry, bool> hideExpired = delegate(PwEntry e) { DateTime dtNow = DateTime.UtcNow; if (e.Expires && (e.ExpiryTime <= dtNow)) { return(false); } return(true); }; if (configOpt.HideExpired) { result = from e in result where hideExpired(e.entry) select e; } return(result); }
private PwEntry GetConfigEntry(bool create) { var root = host.Database.RootGroup; // Get stored RootGroup from config if any var configOpt = new ConfigOpt(this.host.CustomConfig); if (configOpt.RootGroup != "") { var GroupUuid = new PwUuid(StringToByteArray(configOpt.RootGroupUuid)); root = root.FindGroup(GroupUuid, true); } var uuid = new PwUuid(KEEPASSHTTP_UUID); var entry = root.FindEntry(uuid, false); if (entry == null && create) { entry = new PwEntry(false, true); entry.Uuid = uuid; entry.Strings.Set(PwDefs.TitleField, new ProtectedString(false, KEEPASSHTTP_NAME)); root.AddEntry(entry, true); UpdateUI(null); } return entry; }
private bool UpdateEntry(PwUuid uuid, string username, string password, string formHost, string requestId) { PwEntry entry = null; var configOpt = new ConfigOpt(this.host.CustomConfig); if (configOpt.SearchInAllOpenedDatabases) { foreach (PwDocument doc in host.MainWindow.DocumentManager.Documents) { if (doc.Database.IsOpen) { entry = doc.Database.RootGroup.FindEntry(uuid, true); if (entry != null) { break; } } } } else { entry = host.Database.RootGroup.FindEntry(uuid, true); } if (entry == null) { return(false); } string[] up = GetUserPass(entry); var u = up[0]; var p = up[1]; if (u != username || p != password) { bool allowUpdate = configOpt.AlwaysAllowUpdates; if (!allowUpdate) { host.MainWindow.Activate(); DialogResult result; if (host.MainWindow.IsTrayed()) { result = MessageBox.Show( String.Format("Do you want to update the information in {0} - {1}?", formHost, u), "Update Entry", MessageBoxButtons.YesNo, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } else { result = MessageBox.Show( host.MainWindow, String.Format("Do you want to update the information in {0} - {1}?", formHost, u), "Update Entry", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); } if (result == DialogResult.Yes) { allowUpdate = true; } } if (allowUpdate) { PwObjectList <PwEntry> m_vHistory = entry.History.CloneDeep(); entry.History = m_vHistory; entry.CreateBackup(null); entry.Strings.Set(PwDefs.UserNameField, new ProtectedString(false, username)); entry.Strings.Set(PwDefs.PasswordField, new ProtectedString(true, password)); entry.Touch(true, false); UpdateUI(entry.ParentGroup); return(true); } } return(false); }
private void GetLoginsHandler(Request r, Response resp, Aes aes) { if (!VerifyRequest(r, aes)) { return; } string submithost = null; var host = GetHost(CryptoTransform(r.Url, true, false, aes, CMode.DECRYPT)); if (r.SubmitUrl != null) { submithost = GetHost(CryptoTransform(r.SubmitUrl, true, false, aes, CMode.DECRYPT)); } var items = FindMatchingEntries(r, aes); if (items.ToList().Count > 0) { Func <PwEntry, bool> filter = delegate(PwEntry e) { var c = GetEntryConfig(e); var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); if (c != null) { return(title != host && entryUrl != host && !c.Allow.Contains(host) || (submithost != null && !c.Allow.Contains(submithost) && submithost != title && submithost != entryUrl)); } return(title != host && entryUrl != host || (submithost != null && title != submithost && entryUrl != submithost)); }; var config = GetConfigEntry(true); var autoAllowS = config.Strings.ReadSafe("Auto Allow"); var autoAllow = autoAllowS != null && autoAllowS.Trim() != ""; var needPrompting = from e in items where filter(e) select e; if (needPrompting.ToList().Count > 0 && !autoAllow) { var wait = new ManualResetEvent(false); var clicked = false; var delegated = false; EventHandler onclick = delegate { delegated = true; clicked = true; wait.Set(); }; EventHandler onclose = delegate { delegated = true; wait.Set(); }; ShowNotification(String.Format( "{0}: {1} is requesting access, click to allow or deny", r.Id, submithost != null ? submithost : host), onclick, onclose); wait.WaitOne(GetNotificationTime() + 5000); // give a little time to fade if (!delegated) { resp.Error = "Notification bubble did not appear"; } if (clicked) { var win = this.host.MainWindow; using (var f = new AccessControlForm()) { win.Invoke((MethodInvoker) delegate { f.Icon = win.Icon; f.Plugin = this; f.Entries = needPrompting.ToList(); f.Host = submithost != null ? submithost : host; f.Load += delegate { f.Activate(); }; f.ShowDialog(win); if (f.Remember && (f.Allowed || f.Denied)) { foreach (var e in needPrompting) { var c = GetEntryConfig(e); if (c == null) { c = new KeePassHttpEntryConfig(); } var set = f.Allowed ? c.Allow : c.Deny; set.Add(host); if (submithost != null && submithost != host) { set.Add(submithost); } SetEntryConfig(e, c); } } if (!f.Allowed) { items = items.Except(needPrompting); } }); } } else { items = items.Except(needPrompting); } } foreach (var entry in items) { var name = entry.Strings.ReadSafe(PwDefs.TitleField); var loginpass = GetUserPass(entry); var login = loginpass[0]; var passwd = loginpass[1]; var uuid = entry.Uuid.ToHexString(); var e = new ResponseEntry(name, login, passwd, uuid); resp.Entries.Add(e); } if (items.ToList().Count > 0) { var names = (from e in resp.Entries select e.Name).Distinct <string>(); var n = String.Join("\n ", names.ToArray <string>()); var configOpt = new ConfigOpt(this.host.CustomConfig); 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); } } }