public OptionsForm(ConfigOpt config) { _host = NativeMessagingHost.GetHost(); _config = config; InitializeComponent(); lblVersion.Text = string.Format("KeePassNatMsg v{0}", AssemblyVersion); }
public Response ProcessRequest(Request req) { var handler = GetHandler(req.Action); if (handler != null) { if (handler != ChangePublicKeys) { lock (_unlockLock) { var config = new ConfigOpt(_host.CustomConfig); if (!_host.Database.IsOpen && config.UnlockDatabaseRequest) { if (KeePass.UI.GlobalWindowManager.WindowCount == 0) { _host.MainWindow.Invoke(new System.Action(() => _host.MainWindow.OpenDatabase(_host.MainWindow.DocumentManager.ActiveDocument.LockedIoc, null, false))); } } if (!_host.Database.IsOpen) { return(new ErrorResponse(req, ErrorType.DatabaseNotOpened)); } } } return(handler.Invoke(req)); } return(new ErrorResponse(req, ErrorType.IncorrectAction)); }
private PwEntryDatabase FindEntry(string uuid) { PwUuid id = new PwUuid(MemUtil.HexStringToByteArray(uuid)); var configOpt = new ConfigOpt(_host.CustomConfig); if (configOpt.SearchInAllOpenedDatabases) { foreach (var doc in _host.MainWindow.DocumentManager.Documents) { if (doc.Database.IsOpen) { var entry = doc.Database.RootGroup.FindEntry(id, true); if (entry != null) { return(new PwEntryDatabase(entry, doc.Database)); } } } } else { var entry = _host.Database.RootGroup.FindEntry(id, true); if (entry != null) { return(new PwEntryDatabase(entry, _host.Database)); } } return(null); }
private bool UnlockDatabase(bool triggerUnlock) { lock (_unlockLock) { var config = new ConfigOpt(_host.CustomConfig); if (!_host.Database.IsOpen && config.UnlockDatabaseRequest && KeePass.UI.GlobalWindowManager.WindowCount == 0 && triggerUnlock) { _host.MainWindow.Invoke(new System.Action(() => _host.MainWindow.OpenDatabase(_host.MainWindow.DocumentManager.ActiveDocument.LockedIoc, null, false))); } return(_host.Database.IsOpen); } }
private static IEnumerable <KeyValuePair <string, string> > GetFields(ConfigOpt configOpt, PwEntryDatabase entryDatabase) { SprContext ctx = new SprContext(entryDatabase.entry, entryDatabase.database, SprCompileFlags.All, false, false); List <KeyValuePair <string, string> > fields = null; if (configOpt.ReturnStringFields) { fields = new List <KeyValuePair <string, string> >(); foreach (var sf in entryDatabase.entry.Strings) { var sfValue = entryDatabase.entry.Strings.ReadSafe(sf.Key); // follow references sfValue = SprEngine.Compile(sfValue, ctx); // KeeOtp support through keepassxc-browser // KeeOtp stores the TOTP config in a string field "otp" and provides a placeholder "{TOTP}" // KeeTrayTOTP uses by default a "TOTP Seed" string field, and the {TOTP} placeholder. // keepassxc-browser needs the value in a string field named "KPH: {TOTP}" if (sf.Key == "otp" || sf.Key.Equals("TOTP Seed", StringComparison.InvariantCultureIgnoreCase)) { fields.Add(new KeyValuePair <string, string>("KPH: {TOTP}", SprEngine.Compile("{TOTP}", ctx))); } else if (configOpt.ReturnStringFieldsWithKphOnly) { if (sf.Key.StartsWith("KPH: ")) { fields.Add(new KeyValuePair <string, string>(sf.Key.Substring(5), sfValue)); } } else { fields.Add(new KeyValuePair <string, string>(sf.Key, sfValue)); } } if (fields.Count > 0) { var sorted = from e2 in fields orderby e2.Key ascending select e2; fields = sorted.ToList(); } else { fields = null; } } return(fields); }
public string GenerateFromUuid(string uuid) { PwEntry entry = null; PwUuid id = new PwUuid(MemUtil.HexStringToByteArray(uuid)); var configOpt = new ConfigOpt(_host.CustomConfig); if (configOpt.SearchInAllOpenedDatabases) { foreach (PwDocument doc in _host.MainWindow.DocumentManager.Documents) { if (doc.Database.IsOpen) { entry = doc.Database.RootGroup.FindEntry(id, true); if (entry != null) { break; } } } } else { entry = _host.Database.RootGroup.FindEntry(id, true); } if (entry == null) { return(string.Empty); } string TotpSettings = _ext.GetTotpSettings(entry); if (TotpSettings == null) { return(string.Empty); } try { return(Totp.Generate(TotpSettings)); } catch (Exception) { return(string.Empty); } }
private IEnumerable <KeyValuePair <string, string> > GetFields(ConfigOpt configOpt, PwEntryDatabase entryDatabase) { SprContext ctx = new SprContext(entryDatabase.entry, entryDatabase.database, SprCompileFlags.All, false, false); List <KeyValuePair <string, string> > fields = null; if (configOpt.ReturnStringFields) { fields = new List <KeyValuePair <string, string> >(); 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 KeyValuePair <string, string>(sf.Key.Substring(5), sfValue)); } } else { fields.Add(new KeyValuePair <string, string>(sf.Key, sfValue)); } } if (fields.Count > 0) { var sorted = from e2 in fields orderby e2.Key ascending select e2; fields = sorted.ToList(); } else { fields = null; } } return(fields); }
public bool UpdateEntry(string uuid, string username, string password, string formHost) { PwEntry entry = null; PwUuid id = new PwUuid(MemUtil.HexStringToByteArray(uuid)); PwDatabase db = null; var configOpt = new ConfigOpt(_host.CustomConfig); if (configOpt.SearchInAllOpenedDatabases) { foreach (PwDocument doc in _host.MainWindow.DocumentManager.Documents) { if (doc.Database.IsOpen) { entry = doc.Database.RootGroup.FindEntry(id, true); if (entry != null) { db = doc.Database; break; } } } } else { entry = _host.Database.RootGroup.FindEntry(id, true); db = _host.Database; } if (entry == null) { return(false); } string[] up = _ext.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); _ext.UpdateUI(entry.ParentGroup); AutoSaveIfRequired(db); return(true); } } return(false); }
private IEnumerable <PwEntryDatabase> FindMatchingEntries(string url, string realm) { var listResult = new List <PwEntryDatabase>(); var hostUri = new Uri(url); var formHost = hostUri.Host; var searchHost = hostUri.Host; var origSearchHost = hostUri.Host; var parms = MakeSearchParameters(); List <PwDatabase> listDatabases = new List <PwDatabase>(); var configOpt = new ConfigOpt(_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; } var searchUrls = configOpt.SearchUrls; bool filter(PwEntry e) { var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); var c = _ext.GetEntryConfig(e); if (c != null) { if (c.Allow.Contains(formHost)) { return(true); } if (c.Deny.Contains(formHost)) { return(false); } if (!string.IsNullOrEmpty(realm) && c.Realm != realm) { return(false); } } if (IsValidUrl(entryUrl, formHost)) { return(true); } if (IsValidUrl(title, formHost)) { return(true); } if (searchUrls) { foreach (var sf in e.Strings.Where(s => s.Key.StartsWith("URL", StringComparison.InvariantCultureIgnoreCase))) { var sfv = e.Strings.ReadSafe(sf.Key); if (sf.Key.IndexOf("regex", StringComparison.OrdinalIgnoreCase) >= 0 && System.Text.RegularExpressions.Regex.IsMatch(formHost, sfv)) { return(true); } if (IsValidUrl(sfv, formHost)) { return(true); } } } return(formHost.Contains(title) || (!string.IsNullOrEmpty(entryUrl) && formHost.Contains(entryUrl))); } bool filterSchemes(PwEntry e) { var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); if (entryUrl != null && Uri.TryCreate(entryUrl, UriKind.Absolute, out var entryUri) && entryUri.Scheme == hostUri.Scheme) { return(true); } if (Uri.TryCreate(title, UriKind.Absolute, out var titleUri) && titleUri.Scheme == hostUri.Scheme) { return(true); } return(false); } var result = listResult.Where(e => filter(e.entry)); if (configOpt.MatchSchemes) { result = result.Where(e => filterSchemes(e.entry)); } if (configOpt.HideExpired) { result = result.Where(x => !(x.entry.Expires && x.entry.ExpiryTime <= DateTime.UtcNow)); } return(result); }
internal Response GetLoginsHandler(Request req) { if (!req.TryDecrypt()) { return(new ErrorResponse(req, ErrorType.CannotDecryptMessage)); } var msg = req.Message; var id = msg.GetString("id"); var url = msg.GetString("url"); var submitUrl = msg.GetString("submitUrl"); Uri hostUri; Uri submitUri; if (!string.IsNullOrEmpty(url)) { hostUri = new Uri(url); } else { return(new ErrorResponse(req, ErrorType.NoUrlProvided)); } if (!string.IsNullOrEmpty(submitUrl)) { submitUri = new Uri(submitUrl); } else { submitUri = hostUri; } var resp = req.GetResponse(); resp.Message.Add("id", id); var items = FindMatchingEntries(url, null); if (items.ToList().Count > 0) { bool filter(PwEntry e) { var c = _ext.GetEntryConfig(e); var title = e.Strings.ReadSafe(PwDefs.TitleField); var entryUrl = e.Strings.ReadSafe(PwDefs.UrlField); if (c != null) { return((title != hostUri.Host && entryUrl != hostUri.Host && !c.Allow.Contains(hostUri.Host)) || (submitUri.Host != null && !c.Allow.Contains(submitUri.Host) && submitUri.Host != title && submitUri.Host != entryUrl)); } return((title != hostUri.Host && entryUrl != hostUri.Host) || (submitUri.Host != null && title != submitUri.Host && entryUrl != submitUri.Host)); } var configOpt = new ConfigOpt(_host.CustomConfig); var config = _ext.GetConfigEntry(true); var autoAllowS = config.Strings.ReadSafe("Auto Allow"); var autoAllow = !string.IsNullOrWhiteSpace(autoAllowS); autoAllow = autoAllow || configOpt.AlwaysAllowAccess; var needPrompting = from e in items where filter(e.entry) select e; if (needPrompting.ToList().Count > 0 && !autoAllow) { var win = _host.MainWindow; using (var f = new AccessControlForm()) { win.Invoke((MethodInvoker) delegate { f.Icon = win.Icon; f.Plugin = _ext; f.Entries = (from e in items where filter(e.entry) select e.entry).ToList(); //f.Entries = needPrompting.ToList(); f.Host = submitUri.Host ?? hostUri.Host; f.Load += delegate { f.Activate(); }; f.ShowDialog(win); if (f.Remember && (f.Allowed || f.Denied)) { foreach (var e in needPrompting) { var c = _ext.GetEntryConfig(e.entry) ?? new EntryConfig(); var set = f.Allowed ? c.Allow : c.Deny; set.Add(hostUri.Host); if (submitUri.Host != null && submitUri.Host != hostUri.Host) { set.Add(submitUri.Host); } _ext.SetEntryConfig(e.entry, c); } } if (!f.Allowed) { items = items.Except(needPrompting); } }); } } 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(submitUri.ToString().ToLower(), 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, _ext.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(); } var entries = new JArray(itemsList.Select(item => { var up = _ext.GetUserPass(item); var TotpSettings = _ext.GetTotpSettings(item.entry); JArray fldArr = null; var fields = GetFields(configOpt, item); if (fields != null) { fldArr = new JArray(fields.Select(f => new JObject { { f.Key, f.Value } })); } string fldTotp = null; if (TotpSettings != null) { fldTotp = Totp.Generate(TotpSettings); } return(new JObject { { "name", item.entry.Strings.ReadSafe(PwDefs.TitleField) }, { "login", up[0] }, { "password", up[1] }, { "uuid", item.entry.Uuid.ToHexString() }, { "totp", fldTotp }, { "stringFields", fldArr } }); })); resp.Message.Add("count", itemsList.Count); resp.Message.Add("entries", entries); if (itemsList.Count > 0) { var names = (from e in itemsList select e.entry.Strings.ReadSafe(PwDefs.TitleField)).Distinct(); var n = String.Join("\n ", names); if (configOpt.ReceiveCredentialNotification) { _ext.ShowNotification(String.Format("{0}: {1} is receiving credentials for:\n {2}", req.GetString("id"), hostUri.Host, n)); } } return(resp); } resp.Message.Add("count", 0); resp.Message.Add("entries", new JArray()); return(resp); }
public OptionsForm(ConfigOpt config) { _host = NativeMessagingHost.GetHost(); _config = config; InitializeComponent(); }
private IEnumerable <PwEntryDatabase> FindMatchingEntries(string url, string submitUrl, string realm) { string submitHost = null; var listResult = new List <PwEntryDatabase>(); var hostUri = new Uri(url); var formHost = hostUri.Host; var searchHost = hostUri.Host; var origSearchHost = hostUri.Host; var parms = MakeSearchParameters(); List <PwDatabase> listDatabases = new List <PwDatabase>(); var configOpt = new ConfigOpt(_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 = _ext.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 = new Uri(entryUrl); if (formHost.EndsWith(uHost.Host)) { return(true); } } if (title.StartsWith("http://") || title.StartsWith("https://") || title.StartsWith("ftp://") || title.StartsWith("sftp://")) { var uHost = new Uri(title); if (formHost.EndsWith(uHost.Host)) { 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) { if (Uri.TryCreate(entryUrl, UriKind.Absolute, out var entryUri) && entryUri.Scheme == hostUri.Scheme) { return(true); } } if (Uri.TryCreate(title, UriKind.Absolute, out var titleUri) && titleUri.Scheme == hostUri.Scheme) { 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); }
internal Response GetLoginsHandler(Request req) { if (!req.TryDecrypt()) { return(new ErrorResponse(req, ErrorType.CannotDecryptMessage)); } var msg = req.Message; var id = msg.GetString("id"); var url = msg.GetString("url"); var submitUrl = msg.GetString("submitUrl"); Uri hostUri; Uri submitUri = null; if (!string.IsNullOrEmpty(url)) { hostUri = new Uri(url); } else { return(new ErrorResponse(req, ErrorType.NoUrlProvided)); } if (!string.IsNullOrEmpty(submitUrl)) { submitUri = new Uri(submitUrl); } var resp = req.GetResponse(); resp.Message.Add("id", id); var items = FindMatchingEntries(url, null); if (items.ToList().Count > 0) { var filter = new GFunc <PwEntry, bool>((PwEntry e) => { var c = _ext.GetEntryConfig(e); return(c == null || (!c.Allow.Contains(hostUri.Authority)) || (submitUri != null && submitUri.Authority != null && !c.Allow.Contains(submitUri.Authority))); }); var configOpt = new ConfigOpt(_host.CustomConfig); var needPrompting = items.Where(e => filter(e.entry)).ToList(); if (needPrompting.Count > 0 && !configOpt.AlwaysAllowAccess) { var win = _host.MainWindow; using (var f = new AccessControlForm()) { win.Invoke((MethodInvoker) delegate { f.Icon = win.Icon; f.Plugin = _ext; f.StartPosition = win.Visible ? FormStartPosition.CenterParent : FormStartPosition.CenterScreen; f.Entries = needPrompting.Select(e => e.entry).ToList(); f.Host = submitUri != null ? submitUri.Authority : hostUri.Authority; f.Load += delegate { f.Activate(); }; f.ShowDialog(win); if (f.Remember && (f.Allowed || f.Denied)) { foreach (var e in needPrompting) { var c = _ext.GetEntryConfig(e.entry) ?? new EntryConfig(); var set = f.Allowed ? c.Allow : c.Deny; set.Add(hostUri.Authority); if (submitUri != null && submitUri.Authority != null && submitUri.Authority != hostUri.Authority) { set.Add(submitUri.Authority); } _ext.SetEntryConfig(e.entry, c); } } if (!f.Allowed) { items = items.Except(needPrompting); } }); } } var uri = submitUri != null ? submitUri : hostUri; 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(uri.ToString().ToLower(), 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, _ext.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(); } var entries = new JArray(itemsList.Select(item => { var up = _ext.GetUserPass(item); JArray fldArr = null; var fields = GetFields(configOpt, item); if (fields != null) { fldArr = new JArray(fields.Select(f => new JObject { { f.Key, f.Value } })); } var jobj = new JObject { { "name", item.entry.Strings.ReadSafe(PwDefs.TitleField) }, { "login", up[0] }, { "password", up[1] }, { "uuid", item.entry.Uuid.ToHexString() }, { "stringFields", fldArr }, }; CheckTotp(item, jobj); return(jobj); })); resp.Message.Add("count", itemsList.Count); resp.Message.Add("entries", entries); if (itemsList.Count > 0) { var names = (from e in itemsList select e.entry.Strings.ReadSafe(PwDefs.TitleField)).Distinct(); var n = String.Join("\n ", names); if (configOpt.ReceiveCredentialNotification) { _ext.ShowNotification(String.Format("{0}: {1} is receiving credentials for:\n {2}", req.GetString("id"), hostUri.Host, n)); } } return(resp); } resp.Message.Add("count", 0); resp.Message.Add("entries", new JArray()); return(resp); }