Пример #1
0
        /// <summary>
        /// Deserializes this node by using the <see cref="KdbxMetadata"/> binary collection
        /// to dereference @Ref.
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="metadata">Used to dereference the Ref attribute.</param>
        /// <param name="parameters"></param>
        public KdbxBinAttachment(XElement xml, KdbxMetadata metadata, KdbxSerializationParameters parameters)
            : base(xml)
        {
            FileName = GetString("Key", true);

            XElement valueNode = GetNode("Value");

            if (valueNode == null)
            {
                throw new KdbxParseException(
                          ReaderResult.FromXmlParseFailure($"Node {rootName} missing required child Value")
                          );
            }

            int    refId;
            string refAttr = valueNode.Attribute("Ref")?.Value;

            if (refAttr == null || !int.TryParse(refAttr, out refId))
            {
                throw new KdbxParseException(
                          ReaderResult.FromXmlParseFailure($"Child Value node of {rootName} missing required int @Ref")
                          );
            }

            Data = metadata.Binaries.GetById(refId);
            this.binaryCollection = metadata.Binaries;
        }
Пример #2
0
        public KdbxEntry(IKeePassGroup parent, IRandomNumberGenerator rng, KdbxMetadata metadata)
            : this(false)
        {
            DebugHelper.Assert(parent != null);
            DebugHelper.Assert(rng != null);
            if (rng == null)
            {
                throw new ArgumentNullException("rng");
            }

            DebugHelper.Assert(metadata != null);
            if (metadata == null)
            {
                throw new ArgumentNullException("metadata");
            }

            Parent  = parent ?? throw new ArgumentNullException("parent");
            Uuid    = new KeePassUuid();
            IconID  = KdbxEntry.DefaultIconId;
            Times   = new KdbxTimes();
            History = new KdbxHistory(metadata);

            KdbxMemoryProtection memProtection = metadata.MemoryProtection;
            Title = new KdbxString("Title", string.Empty, rng, memProtection.ProtectTitle);
            string initialUsername = metadata.DefaultUserName ?? string.Empty;
            UserName       = new KdbxString("UserName", initialUsername, rng, memProtection.ProtectUserName);
            Password       = new KdbxString("Password", string.Empty, rng, memProtection.ProtectPassword);
            Url            = new KdbxString("URL", string.Empty, rng, memProtection.ProtectUrl);
            Notes          = new KdbxString("Notes", string.Empty, rng, memProtection.ProtectNotes);
            Tags           = string.Empty;
            OverrideUrl    = string.Empty;
            this._metadata = metadata;
        }
Пример #3
0
        /// <summary>
        /// Parses a KeePass document from the specified XML.
        /// </summary>
        /// <param name="xml">XML to deserialize.</param>
        /// <param name="headerBinaries">Any binaries that were parsed from a header.</param>
        /// <param name="rng">RNG used to encrypt protected strings.</param>
        /// <param name="parameters">Parameters controlling serialization.</param>
        public KdbxDocument(XElement xml, IEnumerable <ProtectedBinary> headerBinaries, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
            : base(xml)
        {
            XElement metadata = GetNode(KdbxMetadata.RootName);

            if (metadata == null)
            {
                throw new KdbxParseException(
                          ReaderResult.FromXmlParseFailure($"Document has no {KdbxMetadata.RootName} node")
                          );
            }
            Metadata = new KdbxMetadata(metadata, headerBinaries, parameters);

            XElement root = GetNode(KdbxRoot.RootName);

            if (root == null)
            {
                throw new KdbxParseException(
                          ReaderResult.FromXmlParseFailure($"Document has no {KdbxRoot.RootName} node")
                          );
            }
            Root = new KdbxRoot(root, rng, Metadata, parameters);
        }
Пример #4
0
        public KdbxGroup(XElement xml, IKeePassGroup parent, IRandomNumberGenerator rng, KdbxMetadata metadata, KdbxSerializationParameters parameters)
            : base(xml, parameters)
        {
            InitializeCollections();

            Parent = parent;

            Title = new KdbxString("Name", GetString("Name"), null);
            Notes = new KdbxString("Notes", GetString("Notes"), null);

            IsExpanded = GetBool("IsExpanded");
            DefaultAutoTypeSequence = GetString("DefaultAutoTypeSequence");
            EnableAutoType          = GetNullableBool("EnableAutoType");
            EnableSearching         = GetNullableBool("EnableSearching");
            LastTopVisibleEntry     = GetUuid("LastTopVisibleEntry", false) ?? KeePassUuid.Empty;

            // The order in which we deserialize entries and groups matters.
            // They must be constructed in the order that they appear in the XML,
            // or the RNG will enter undefined territory.
            ForgetNodes(KdbxEntry.RootName);
            ForgetNodes(KdbxGroup.RootName);

            // First, we need to select each XElement that represents either a group or an entry.
            // From these, we construct KdbxEntries and KdbxGroups.
            // Then we sort them, groups first, and add them to the child collection.
            IEnumerable <IKeePassNode> nodes = xml.Elements()
                                               .Where(element => element.Name == KdbxEntry.RootName || element.Name == KdbxGroup.RootName)
                                               .Select(
                matchedElement =>
            {
                if (matchedElement.Name == KdbxEntry.RootName)
                {
                    return(new KdbxEntry(matchedElement, this, rng, metadata, parameters)
                           as IKeePassNode);
                }
                else
                {
                    return(new KdbxGroup(matchedElement, this, rng, metadata, parameters)
                           as IKeePassNode);
                }
            }
                )
                                               .OrderBy(
                node => node is IKeePassGroup,
                Comparer <bool> .Create((b1, b2) => b1.CompareTo(b2))
                );

            foreach (IKeePassNode node in nodes)
            {
                this._children.Add(node);
            }
        }
Пример #5
0
 public KdbxRoot(XElement xml, IRandomNumberGenerator rng, KdbxMetadata metadata, KdbxSerializationParameters parameters)
     : base(xml)
 {
     DatabaseGroup    = new KdbxGroup(GetNode(KdbxGroup.RootName), null, rng, metadata, parameters);
     this.deletedObjs = GetNode("DeletedObjects");
 }
Пример #6
0
        public override bool Equals(object obj)
        {
            KdbxMetadata other = obj as KdbxMetadata;

            if (other == null)
            {
                return(false);
            }

            if (Generator != other.Generator)
            {
                return(false);
            }

            if (DatabaseName != other.DatabaseName || DatabaseDescription != other.DatabaseDescription)
            {
                return(false);
            }

            if (DatabaseNameChanged != other.DatabaseNameChanged || DatabaseDescriptionChanged != other.DatabaseDescriptionChanged)
            {
                return(false);
            }

            if (DefaultUserName != other.DefaultUserName || DefaultUserNameChanged != other.DefaultUserNameChanged)
            {
                return(false);
            }

            if (MaintenanceHistoryDays != other.MaintenanceHistoryDays)
            {
                return(false);
            }

            if (DbColor != other.DbColor)
            {
                return(false);
            }

            if (MasterKeyChanged != other.MasterKeyChanged ||
                MasterKeyChangeRec != other.MasterKeyChangeRec ||
                MasterKeyChangeForce != other.MasterKeyChangeForce)
            {
                return(false);
            }

            if (!MemoryProtection.Equals(other.MemoryProtection))
            {
                return(false);
            }

            if (CustomIcons != null)
            {
                if (!CustomIcons.Equals(other.CustomIcons))
                {
                    return(false);
                }
            }
            else
            {
                if (other.CustomIcons != null)
                {
                    return(false);
                }
            }

            if (RecycleBinEnabled != other.RecycleBinEnabled ||
                !RecycleBinUuid.Equals(other.RecycleBinUuid) ||
                RecycleBinChanged != other.RecycleBinChanged)
            {
                return(false);
            }

            if (!EntryTemplatesGroup.Equals(other.EntryTemplatesGroup) || EntryTemplatesGroupChanged != other.EntryTemplatesGroupChanged)
            {
                return(false);
            }

            if (HistoryMaxItems != other.HistoryMaxItems || HistoryMaxSize != other.HistoryMaxSize)
            {
                return(false);
            }

            if (!LastSelectedGroup.Equals(other.LastSelectedGroup) || !LastTopVisibleGroup.Equals(other.LastTopVisibleGroup))
            {
                return(false);
            }

            if (Binaries != null)
            {
                if (!Binaries.Equals(other.Binaries))
                {
                    return(false);
                }
            }
            else
            {
                if (other.Binaries != null)
                {
                    return(false);
                }
            }

            if (CustomData != null)
            {
                if (!CustomData.Equals(other.CustomData))
                {
                    return(false);
                }
            }
            else
            {
                if (other.CustomData != null)
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #7
0
 /// <summary>
 /// Initializes an empty document with provided metadata.
 /// </summary>
 /// <param name="metadata"></param>
 public KdbxDocument(KdbxMetadata metadata)
 {
     Metadata = metadata;
     Root     = new KdbxRoot();
 }
Пример #8
0
        public KdbxEntry(XElement xml, IKeePassGroup parent, IRandomNumberGenerator rng, KdbxMetadata metadata, KdbxSerializationParameters parameters)
            : base(xml, parameters)
        {
            Parent = parent;

            ForegroundColor = GetNullableColor("ForegroundColor");
            BackgroundColor = GetNullableColor("BackgroundColor");
            OverrideUrl     = GetString("OverrideURL") ?? string.Empty;
            Tags            = GetString("Tags") ?? string.Empty;

            Fields = new ObservableCollection <IProtectedString>();
            IEnumerable <KdbxString> strings = GetNodes(KdbxString.RootName)
                                               .Select(x => new KdbxString(x, rng));

            foreach (KdbxString s in strings)
            {
                switch (s.Key)
                {
                case "Notes":
                    Notes = s;
                    break;

                case "Password":
                    Password = s;
                    break;

                case "Title":
                    Title = s;
                    break;

                case "URL":
                    Url = s;
                    break;

                case "UserName":
                    UserName = s;
                    break;

                default:
                    Fields.Add(s);
                    break;
                }
            }

            KdbxMemoryProtection memProtection = metadata.MemoryProtection;

            if (Password == null)
            {
                Password = new KdbxString("Password", string.Empty, rng, memProtection.ProtectPassword);
            }
            if (Title == null)
            {
                Title = new KdbxString("Title", string.Empty, rng, memProtection.ProtectTitle);
            }
            if (Url == null)
            {
                Url = new KdbxString("URL", string.Empty, rng, memProtection.ProtectUrl);
            }
            if (UserName == null)
            {
                UserName = new KdbxString("UserName", string.Empty, rng, memProtection.ProtectUserName);
            }
            if (Notes == null)
            {
                Notes = new KdbxString("Notes", string.Empty, rng, memProtection.ProtectNotes);
            }

            IEnumerable <KdbxBinAttachment> binNodes = GetNodes(KdbxBinAttachment.RootName).Select(x => new KdbxBinAttachment(x, metadata, parameters));

            Binaries = new ObservableCollection <IKeePassBinAttachment>(binNodes);

            XElement autoTypeNode = GetNode(KdbxAutoType.RootName);

            if (autoTypeNode != null)
            {
                AutoType = new KdbxAutoType(autoTypeNode);
            }

            XElement historyElement = GetNode(KdbxHistory.RootName);

            if (historyElement != null)
            {
                History = new KdbxHistory(historyElement, rng, metadata, parameters);
            }
            else
            {
                History = new KdbxHistory(metadata);
            }

            this._metadata = metadata;
        }
Пример #9
0
 /// <summary>
 /// Helper that deserializes an entry as a history entry (no parent).
 /// </summary>
 /// <param name="xml"></param>
 /// <param name="rng"></param>
 /// <param name="metadata"></param>
 /// <param name="parameters"></param>
 public KdbxEntry(XElement xml, IRandomNumberGenerator rng, KdbxMetadata metadata, KdbxSerializationParameters parameters)
     : this(xml, null, rng, metadata, parameters)
 {
     this.isHistoryEntry = true;
     History             = null;
 }