Exemple #1
0
        private static KdbErrorCode SetDatabaseKey(KdbManager mgr, CompositeKey pwKey)
        {
            KdbErrorCode e;

            bool bPassword = pwKey.ContainsType(typeof(KcpPassword));
            bool bKeyFile  = pwKey.ContainsType(typeof(KcpKeyFile));

            string strPassword = (bPassword ? (pwKey.GetUserKey(
                                                   typeof(KcpPassword)) as KcpPassword).Password.ReadString() : string.Empty);
            string strKeyFile = (bKeyFile ? (pwKey.GetUserKey(
                                                 typeof(KcpKeyFile)) as KcpKeyFile).Path : string.Empty);

            if (bPassword && bKeyFile)
            {
                e = mgr.SetMasterKey(strKeyFile, true, strPassword, IntPtr.Zero, false);
            }
            else if (bPassword && !bKeyFile)
            {
                e = mgr.SetMasterKey(strPassword, false, null, IntPtr.Zero, false);
            }
            else if (!bPassword && bKeyFile)
            {
                e = mgr.SetMasterKey(strKeyFile, true, null, IntPtr.Zero, false);
            }
            else if (pwKey.ContainsType(typeof(KcpUserAccount)))
            {
                throw new Exception(KPRes.KdbWUA);
            }
            else
            {
                throw new Exception(KLRes.InvalidCompositeKey);
            }

            return(e);
        }
Exemple #2
0
        /// <summary>
        /// Loads a KDB file and stores all loaded entries in the current
        /// PwDatabase instance.
        /// </summary>
        /// <param name="strFilePath">Relative or absolute path to the file to open.</param>
        public void Load(string strFilePath)
        {
            Debug.Assert(strFilePath != null);
            if (strFilePath == null)
            {
                throw new ArgumentNullException("strFilePath");
            }

            using (KdbManager mgr = new KdbManager())
            {
                KdbErrorCode e;

                e = KdbFile.SetDatabaseKey(mgr, m_pwDatabase.MasterKey);
                if (e != KdbErrorCode.Success)
                {
                    throw new Exception(KLRes.InvalidCompositeKey);
                }

                e = mgr.OpenDatabase(strFilePath, IntPtr.Zero);
                if (e != KdbErrorCode.Success)
                {
                    throw new Exception(KLRes.FileLoadFailed);
                }

                // Copy properties
                m_pwDatabase.KdfParameters = (new AesKdf()).GetDefaultParameters();
                m_pwDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds,
                                                     mgr.KeyTransformationRounds);

                // Read groups and entries
                Dictionary <UInt32, PwGroup> dictGroups = ReadGroups(mgr);
                ReadEntries(mgr, dictGroups);
            }
        }
Exemple #3
0
        private static void EnsureParentGroupsExported(PwGroup pgRoot, ref uint uGroupIndex,
                                                       Dictionary <PwGroup, UInt32> dictGroups, DateTime dtNeverExpires,
                                                       KdbManager mgr)
        {
            bool bHasAtLeastOneGroup = (dictGroups.Count > 0);
            uint uLocalIndex         = uGroupIndex;     // Local copy, can't use ref in delegate

            EntryHandler eh = delegate(PwEntry pe)
            {
                PwGroup pg = pe.ParentGroup;
                if (pg == null)
                {
                    Debug.Assert(false); return(true);
                }
                if (bHasAtLeastOneGroup && (pg == pgRoot))
                {
                    return(true);
                }

                if (dictGroups.ContainsKey(pg))
                {
                    return(true);
                }

                WriteGroup(pg, pgRoot, ref uLocalIndex, dictGroups, dtNeverExpires,
                           mgr, true);
                return(true);
            };

            pgRoot.TraverseTree(TraversalMethod.PreOrder, null, eh);
            uGroupIndex = uLocalIndex;
        }
Exemple #4
0
        /// <summary>
        /// Loads a KDB file and stores all loaded entries in the current
        /// PwDatabase instance.
        /// </summary>
        /// <param name="strFilePath">Relative or absolute path to the file to open.</param>
        public void Load(string strFilePath)
        {
            Debug.Assert(strFilePath != null);
            if (strFilePath == null)
            {
                throw new ArgumentNullException("strFilePath");
            }

            KdbManager   mgr = new KdbManager();
            KdbErrorCode e;

            e = KdbFile.SetDatabaseKey(mgr, m_pwDatabase.MasterKey);
            if (e != KdbErrorCode.Success)
            {
                throw new Exception(KLRes.InvalidCompositeKey);
            }

            e = mgr.OpenDatabase(strFilePath, IntPtr.Zero);
            if (e != KdbErrorCode.Success)
            {
                mgr.Unload();
                throw new Exception(KLRes.FileLoadFailed);
            }

            // Copy properties
            m_pwDatabase.KeyEncryptionRounds = mgr.KeyTransformationRounds;

            // Read groups and entries
            Dictionary <UInt32, PwGroup> dictGroups = ReadGroups(mgr);

            ReadEntries(mgr, dictGroups);

            mgr.Unload();
        }
Exemple #5
0
        /// <summary>
        /// Save the contents of the current <c>PwDatabase</c> to a KDB file.
        /// </summary>
        /// <param name="strSaveToFile">Location to save the KDB file to.</param>
        public void Save(string strSaveToFile, PwGroup pgDataSource)
        {
            Debug.Assert(strSaveToFile != null);
            if (strSaveToFile == null)
            {
                throw new ArgumentNullException("strSaveToFile");
            }

            using (KdbManager mgr = new KdbManager())
            {
                KdbErrorCode e = KdbFile.SetDatabaseKey(mgr, m_pwDatabase.MasterKey);
                if (e != KdbErrorCode.Success)
                {
                    Debug.Assert(false);
                    throw new Exception(KLRes.InvalidCompositeKey);
                }

                if (m_slLogger != null)
                {
                    if (m_pwDatabase.MasterKey.ContainsType(typeof(KcpUserAccount)))
                    {
                        m_slLogger.SetText(KPRes.KdbWUA, LogStatusType.Warning);
                    }

                    if (m_pwDatabase.Name.Length != 0)
                    {
                        m_slLogger.SetText(KdbPrefix + KPRes.FormatNoDatabaseName, LogStatusType.Warning);
                    }
                    if (m_pwDatabase.Description.Length != 0)
                    {
                        m_slLogger.SetText(KdbPrefix + KPRes.FormatNoDatabaseDesc, LogStatusType.Warning);
                    }
                }

                // Set properties
                if (m_pwDatabase.KeyEncryptionRounds >= (ulong)UInt32.MaxValue)
                {
                    mgr.KeyTransformationRounds = 0xFFFFFFFEU;
                }
                else
                {
                    mgr.KeyTransformationRounds = (uint)m_pwDatabase.KeyEncryptionRounds;
                }

                PwGroup pgRoot = (pgDataSource ?? m_pwDatabase.RootGroup);

                // Write groups and entries
                Dictionary <PwGroup, UInt32> dictGroups = WriteGroups(mgr, pgRoot);
                WriteEntries(mgr, dictGroups, pgRoot);

                e = mgr.SaveDatabase(strSaveToFile);
                if (e != KdbErrorCode.Success)
                {
                    throw new Exception(KLRes.FileSaveFailed);
                }
            }
        }
Exemple #6
0
        public static bool IsLibraryInstalled(out Exception ex)
        {
            try
            {
                KdbManager mgr = new KdbManager();
                mgr.Dispose();
            }
            catch (Exception exMgr)
            {
                ex = exMgr;
                return(false);
            }

            ex = null;
            return(true);
        }
Exemple #7
0
        private Dictionary <UInt32, PwGroup> ReadGroups(KdbManager mgr)
        {
            uint uGroupCount = mgr.GroupCount;
            Dictionary <UInt32, PwGroup> dictGroups = new Dictionary <uint, PwGroup>();

            Stack <PwGroup> vGroupStack = new Stack <PwGroup>();

            vGroupStack.Push(m_pwDatabase.RootGroup);

            DateTime dtNeverExpire = KdbManager.GetNeverExpireTime();

            for (uint uGroup = 0; uGroup < uGroupCount; ++uGroup)
            {
                KdbGroup g = mgr.GetGroup(uGroup);

                PwGroup pg = new PwGroup(true, false);

                pg.Name   = g.Name;
                pg.IconId = (g.ImageId < (uint)PwIcon.Count) ? (PwIcon)g.ImageId : PwIcon.Folder;

                pg.CreationTime         = g.CreationTime.ToDateTime();
                pg.LastModificationTime = g.LastModificationTime.ToDateTime();
                pg.LastAccessTime       = g.LastAccessTime.ToDateTime();
                pg.ExpiryTime           = g.ExpirationTime.ToDateTime();

                pg.Expires = (pg.ExpiryTime != dtNeverExpire);

                pg.IsExpanded = ((g.Flags & (uint)KdbGroupFlags.Expanded) != 0);

                while (g.Level < (vGroupStack.Count - 1))
                {
                    vGroupStack.Pop();
                }

                vGroupStack.Peek().AddGroup(pg, true);

                dictGroups[g.GroupId] = pg;

                if (g.Level == (uint)(vGroupStack.Count - 1))
                {
                    vGroupStack.Push(pg);
                }
            }

            return(dictGroups);
        }
Exemple #8
0
        private static void WriteGroup(PwGroup pg, PwGroup pgRoot, ref uint uGroupIndex,
                                       Dictionary <PwGroup, UInt32> dictGroups, DateTime dtNeverExpire,
                                       KdbManager mgr, bool bForceLevel0)
        {
            if (pg == pgRoot)
            {
                return;
            }

            KdbGroup grp = new KdbGroup();

            grp.GroupId    = uGroupIndex;
            dictGroups[pg] = grp.GroupId;

            grp.ImageId = (uint)pg.IconId;
            grp.Name    = pg.Name;
            grp.CreationTime.Set(pg.CreationTime);
            grp.LastModificationTime.Set(pg.LastModificationTime);
            grp.LastAccessTime.Set(pg.LastAccessTime);

            if (pg.Expires)
            {
                grp.ExpirationTime.Set(pg.ExpiryTime);
            }
            else
            {
                grp.ExpirationTime.Set(dtNeverExpire);
            }

            grp.Level = (bForceLevel0 ? (ushort)0 : (ushort)(pg.GetLevel() - 1));

            if (pg.IsExpanded)
            {
                grp.Flags |= (uint)KdbGroupFlags.Expanded;
            }

            if (!mgr.AddGroup(ref grp))
            {
                Debug.Assert(false);
                throw new InvalidOperationException();
            }

            ++uGroupIndex;
        }
Exemple #9
0
        private static KdbErrorCode SetDatabaseKey(KdbManager mgr, CompositeKey pwKey)
        {
            string strPassword = null;

            if (pwKey.ContainsType(typeof(KcpPassword)))
            {
                KcpPassword     p  = (pwKey.GetUserKey(typeof(KcpPassword)) as KcpPassword);
                ProtectedString ps = ((p != null) ? p.Password : null);
                if (ps == null)
                {
                    throw new Exception(KPRes.OptionReqOn + @" '" +
                                        KPRes.MasterPasswordRmbWhileOpen + @"'.");
                }
                strPassword = ps.ReadString();
            }

            string strKeyFile = null;

            if (pwKey.ContainsType(typeof(KcpKeyFile)))
            {
                strKeyFile = (pwKey.GetUserKey(typeof(KcpKeyFile)) as KcpKeyFile).Path;
            }

            KdbErrorCode e;

            if (!string.IsNullOrEmpty(strKeyFile))
            {
                e = mgr.SetMasterKey(strKeyFile, true, strPassword, IntPtr.Zero, false);
            }
            else if (strPassword != null)
            {
                e = mgr.SetMasterKey(strPassword, false, null, IntPtr.Zero, false);
            }
            else if (pwKey.ContainsType(typeof(KcpUserAccount)))
            {
                throw new Exception(KPRes.KdbWUA);
            }
            else
            {
                throw new Exception(KLRes.InvalidCompositeKey);
            }

            return(e);
        }
Exemple #10
0
        private static Dictionary <PwGroup, UInt32> WriteGroups(KdbManager mgr,
                                                                PwGroup pgRoot)
        {
            Dictionary <PwGroup, UInt32> dictGroups = new Dictionary <PwGroup, uint>();

            uint     uGroupIndex   = 1;
            DateTime dtNeverExpire = KdbManager.GetNeverExpireTime();

            GroupHandler gh = delegate(PwGroup pg)
            {
                WriteGroup(pg, pgRoot, ref uGroupIndex, dictGroups, dtNeverExpire,
                           mgr, false);
                return(true);
            };

            pgRoot.TraverseTree(TraversalMethod.PreOrder, gh, null);
            Debug.Assert(dictGroups.Count == (int)(uGroupIndex - 1));

            EnsureParentGroupsExported(pgRoot, ref uGroupIndex, dictGroups,
                                       dtNeverExpire, mgr);
            return(dictGroups);
        }
Exemple #11
0
        private void WriteEntries(KdbManager mgr, Dictionary <PwGroup, uint> dictGroups,
                                  PwGroup pgRoot)
        {
            bool bWarnedOnce = false;
            uint uGroupCount, uEntryCount, uEntriesSaved = 0;

            pgRoot.GetCounts(true, out uGroupCount, out uEntryCount);

            DateTime dtNeverExpire = KdbManager.GetNeverExpireTime();

            EntryHandler eh = delegate(PwEntry pe)
            {
                KdbEntry e = new KdbEntry();

                e.Uuid.Set(pe.Uuid.UuidBytes);

                if (pe.ParentGroup != pgRoot)
                {
                    e.GroupId = dictGroups[pe.ParentGroup];
                }
                else
                {
                    e.GroupId = 1;
                    if ((m_slLogger != null) && !bWarnedOnce)
                    {
                        m_slLogger.SetText(KdbPrefix +
                                           KPRes.FormatNoRootEntries, LogStatusType.Warning);
                        bWarnedOnce = true;
                    }

                    if (dictGroups.Count == 0)
                    {
                        throw new Exception(KPRes.FormatNoSubGroupsInRoot);
                    }
                }

                e.ImageId = (uint)pe.IconId;

                e.Title    = pe.Strings.ReadSafe(PwDefs.TitleField);
                e.UserName = pe.Strings.ReadSafe(PwDefs.UserNameField);
                e.Password = pe.Strings.ReadSafe(PwDefs.PasswordField);
                e.Url      = pe.Strings.ReadSafe(PwDefs.UrlField);

                string strNotes = pe.Strings.ReadSafe(PwDefs.NotesField);
                ExportCustomStrings(pe, ref strNotes);
                ExportAutoType(pe, ref strNotes);
                ExportUrlOverride(pe, ref strNotes);
                e.Additional = strNotes;

                e.PasswordLength = (uint)e.Password.Length;

                Debug.Assert(TimeUtil.PwTimeLength == 7);
                e.CreationTime.Set(pe.CreationTime);
                e.LastModificationTime.Set(pe.LastModificationTime);
                e.LastAccessTime.Set(pe.LastAccessTime);

                if (pe.Expires)
                {
                    e.ExpirationTime.Set(pe.ExpiryTime);
                }
                else
                {
                    e.ExpirationTime.Set(dtNeverExpire);
                }

                IntPtr hBinaryData = IntPtr.Zero;
                if (pe.Binaries.UCount >= 1)
                {
                    foreach (KeyValuePair <string, ProtectedBinary> kvp in pe.Binaries)
                    {
                        e.BinaryDescription = kvp.Key;

                        byte[] pbAttached = kvp.Value.ReadData();
                        e.BinaryDataLength = (uint)pbAttached.Length;

                        if (e.BinaryDataLength > 0)
                        {
                            hBinaryData = Marshal.AllocHGlobal((int)e.BinaryDataLength);
                            Marshal.Copy(pbAttached, 0, hBinaryData, (int)e.BinaryDataLength);

                            e.BinaryData = hBinaryData;
                        }

                        break;
                    }

                    if ((pe.Binaries.UCount > 1) && (m_slLogger != null))
                    {
                        m_slLogger.SetText(KdbPrefix + KPRes.FormatOnlyOneAttachment + "\r\n\r\n" +
                                           KPRes.Entry + ":\r\n" + KPRes.Title + ": " + e.Title + "\r\n" +
                                           KPRes.UserName + ": " + e.UserName, LogStatusType.Warning);
                    }
                }

                bool bResult = mgr.AddEntry(ref e);

                Marshal.FreeHGlobal(hBinaryData);
                hBinaryData = IntPtr.Zero;

                if (!bResult)
                {
                    Debug.Assert(false);
                    throw new InvalidOperationException();
                }

                ++uEntriesSaved;
                if (m_slLogger != null)
                {
                    if (!m_slLogger.SetProgress((100 * uEntriesSaved) / uEntryCount))
                    {
                        return(false);
                    }
                }

                return(true);
            };

            if (!pgRoot.TraverseTree(TraversalMethod.PreOrder, null, eh))
            {
                throw new InvalidOperationException();
            }
        }
Exemple #12
0
        private void ReadEntries(KdbManager mgr, Dictionary <UInt32, PwGroup> dictGroups)
        {
            DateTime dtNeverExpire = KdbManager.GetNeverExpireTime();
            uint     uEntryCount   = mgr.EntryCount;

            for (uint uEntry = 0; uEntry < uEntryCount; ++uEntry)
            {
                KdbEntry e = mgr.GetEntry(uEntry);

                PwGroup pgContainer;
                if (!dictGroups.TryGetValue(e.GroupId, out pgContainer))
                {
                    Debug.Assert(false);
                    continue;
                }

                PwEntry pe = new PwEntry(false, false);
                pe.SetUuid(new PwUuid(e.Uuid.ToByteArray()), false);

                pgContainer.AddEntry(pe, true, true);

                pe.IconId = (e.ImageId < (uint)PwIcon.Count) ? (PwIcon)e.ImageId : PwIcon.Key;

                pe.Strings.Set(PwDefs.TitleField, new ProtectedString(
                                   m_pwDatabase.MemoryProtection.ProtectTitle, e.Title));
                pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(
                                   m_pwDatabase.MemoryProtection.ProtectUserName, e.UserName));
                pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(
                                   m_pwDatabase.MemoryProtection.ProtectPassword, e.Password));
                pe.Strings.Set(PwDefs.UrlField, new ProtectedString(
                                   m_pwDatabase.MemoryProtection.ProtectUrl, e.Url));

                string strNotes = e.Additional;
                ImportAutoType(ref strNotes, pe);
                ImportUrlOverride(ref strNotes, pe);
                pe.Strings.Set(PwDefs.NotesField, new ProtectedString(
                                   m_pwDatabase.MemoryProtection.ProtectNotes, strNotes));

                pe.CreationTime         = e.CreationTime.ToDateTime();
                pe.LastModificationTime = e.LastModificationTime.ToDateTime();
                pe.LastAccessTime       = e.LastAccessTime.ToDateTime();
                pe.ExpiryTime           = e.ExpirationTime.ToDateTime();

                pe.Expires = (pe.ExpiryTime != dtNeverExpire);

                if ((e.BinaryDataLength > 0) && (e.BinaryData != IntPtr.Zero))
                {
                    byte[] pbData = KdbManager.ReadBinary(e.BinaryData, e.BinaryDataLength);
                    Debug.Assert(pbData.Length == e.BinaryDataLength);

                    string strDesc = e.BinaryDescription;
                    if (string.IsNullOrEmpty(strDesc))
                    {
                        strDesc = "Attachment";
                    }

                    pe.Binaries.Set(strDesc, new ProtectedBinary(false, pbData));
                }

                if (m_slLogger != null)
                {
                    if (!m_slLogger.SetProgress((100 * uEntry) / uEntryCount))
                    {
                        throw new Exception(KPRes.Cancel);
                    }
                }
            }
        }