Пример #1
0
        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));
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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;
        }
Пример #5
0
        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);
        }
Пример #6
0
        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()));
        }
Пример #7
0
        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)));
        }
Пример #8
0
        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);
            }
        }
Пример #9
0
        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();
        }
Пример #10
0
        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;
        }
Пример #11
0
        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);
            }
        }
Пример #12
0
        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;
        }
Пример #13
0
        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);
            }
        }
Пример #14
0
        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);
        }
Пример #15
0
        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);
                }
            }
        }
Пример #16
0
        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;
        }
Пример #17
0
        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);
        }
Пример #18
0
        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);
        }
Пример #19
0
        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;
        }
Пример #20
0
 public OptionsForm(ConfigOpt config)
 {
     _config = config;
     InitializeComponent();
 }
Пример #21
0
 public OptionsForm(ConfigOpt config)
 {
     _config = config;
     InitializeComponent();
 }
Пример #22
0
        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);
        }
Пример #23
0
        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;
        }
Пример #24
0
        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();
        }
Пример #25
0
        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);
            }
        }
Пример #26
0
        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);
            }
        }
Пример #27
0
        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);
        }
Пример #28
0
        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);
        }
Пример #29
0
        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;
        }
Пример #30
0
        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);
        }
Пример #31
0
        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);
                }
            }
        }