示例#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 KdbxTimes(XElement xml, KdbxSerializationParameters parameters)
     : base(xml)
 {
     LastModificationTime = GetDate("LastModificationTime", parameters);
     CreationTime         = GetDate("CreationTime", parameters);
     LastAccessTime       = GetDate("LastAccessTime", parameters);
     ExpiryTime           = GetDate("ExpiryTime", parameters);
     Expires         = GetBool("Expires");
     UsageCount      = GetInt("UsageCount");
     LocationChanged = GetDate("LocationChanged", parameters);
 }
示例#3
0
        private XElement GetBizarroNullableBool(string name, bool?value, KdbxSerializationParameters parameters)
        {
            XElement node = GetKeePassNode(name, value, parameters);

            if (String.IsNullOrEmpty(node.Value))
            {
                node.SetValue("null");
            }
            else
            {
                node.Value = node.Value.ToLower();
            }
            return(node);
        }
示例#4
0
        protected KdbxNode(XElement xml, KdbxSerializationParameters parameters)
            : base(xml)
        {
            Uuid           = GetUuid("UUID");
            IconID         = GetInt("IconID");
            CustomIconUuid = GetUuid("CustomIconUUID", false);
            Times          = new KdbxTimes(GetNode(KdbxTimes.RootName), parameters);

            XElement dataElement = GetNode(KdbxCustomData.RootName);

            if (dataElement != null)
            {
                CustomData = new KdbxCustomData(dataElement);
            }
        }
示例#5
0
        /// <summary>
        /// Parses a collection of binaries from the given XML.
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="parameters"></param>
        public KdbxBinaries(XElement xml, KdbxSerializationParameters parameters)
            : base(xml)
        {
            this.binaries = new SortedDictionary <int, KdbxBinary>();

            foreach (XElement ele in GetNodes(KdbxBinary.RootName))
            {
                KdbxBinary bin = new KdbxBinary(ele, parameters);
                if (this.binaries.ContainsKey(bin.Id))
                {
                    throw new KdbxParseException(
                              ReaderResult.FromXmlParseFailure($"Duplicate binary key {bin.Id}")
                              );
                }

                this.binaries.Add(bin.Id, bin);
            }
        }
示例#6
0
        public static string ToKeePassDate(DateTime?dt, KdbxSerializationParameters parameters)
        {
            if (!dt.HasValue)
            {
                return(null);
            }

            if (parameters.UseBase64DateTimeEncoding)
            {
                long   elapsedSeconds = dt.Value.Ticks / TimeSpan.TicksPerSecond;
                byte[] buffer         = ByteHelper.GetLittleEndianBytes((ulong)elapsedSeconds);

                return(CryptographicBuffer.EncodeToBase64String(buffer.AsBuffer()));
            }
            else
            {
                // ToString("s") does not contain the Z UTC timezone specifier, which we want.
                return(dt.Value.ToUniversalTime().ToString("s") + "Z");
            }
        }
示例#7
0
        /// <summary>
        /// Creates an <see cref="XElement"/> that represents this object.
        /// </summary>
        /// <param name="rng">Random number generator used for serializing protected strings.</param>
        /// <param name="parameters">Parameters controlling serialization.</param>
        /// <returns>An XML object that represents the current instance.</returns>
        public XElement ToXml(IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
        {
            XElement xml = new XElement(rootName);

            PopulateChildren(xml, rng, parameters);

            // For each child we didn't parse out earlier during deserialization, add it
            // as-is.
            if (this._pristine != null)
            {
                foreach (var kvp in this._pristine)
                {
                    foreach (XElement node in kvp.Value)
                    {
                        xml.Add(node);
                    }
                }
            }

            return(xml);
        }
示例#8
0
        public DateTime?GetDate(string name, KdbxSerializationParameters parameters, bool required = false)
        {
            string dtString = GetString(name, required);

            if (String.IsNullOrEmpty(dtString))
            {
                return(null);
            }

            // KeePass interop weirdness - they trim the UTC timezone specifier off, then parse,
            // then convert to local time. When serializing they convert back to UTC and add the "Z".
            // Can't say why, but mimicing the behavior to avoid bugs.
            if (dtString.EndsWith("Z"))
            {
                dtString = dtString.Substring(0, dtString.Length - 1);
            }

            DateTime dt;

            if (DateTime.TryParse(dtString, out dt))
            {
                dt = dt.ToLocalTime();
                return(dt);
            }
            else if (parameters.UseBase64DateTimeEncoding)
            {
                // Try to parse the DateTime as a base64 string
                IBuffer data = CryptographicBuffer.DecodeFromBase64String(dtString);
                if (data.Length == 8)
                {
                    long elapsedSeconds = (long)ByteHelper.BufferToLittleEndianUInt64(data.ToArray(), 0);
                    return(new DateTime(elapsedSeconds * TimeSpan.TicksPerSecond, DateTimeKind.Utc));
                }
            }

            // This used to be a parse failure, but due to the strangeness of parsing dates, and because KeePass only considers
            // this an assertion failure with a fallback, we will also fallback.
            DebugHelper.Assert(false, $"Investigate why this DateTime failed to parse: {dtString}");
            return(DateTime.Now);
        }
示例#9
0
        // Internal constructor for initializing fields and checking edge cases
        private KdbxDecryptionResult(ReaderResult error, KdbxSerializationParameters kdbxParameters, KdbxDocument document, IBuffer rawKey)
        {
            DebugHelper.Assert(error != null);
            if (error == null)
            {
                throw new ArgumentNullException(nameof(error));
            }

            if (error != ReaderResult.Success)
            {
                DebugHelper.Assert(document == null);
                if (document != null)
                {
                    throw new ArgumentException("If error is defined, the other arguments must be null");
                }
            }
            else
            {
                // Result is guaranteed to be Success at this point
                DebugHelper.Assert(document != null);
                if (document == null)
                {
                    throw new ArgumentNullException(nameof(document));
                }

                if (rawKey == null)
                {
                    throw new ArgumentNullException(nameof(rawKey));
                }
            }

            Result = error;
            this.kdbxParameters = kdbxParameters;
            this.kdbxDocument   = document;
            this.rawKey         = rawKey;
        }
示例#10
0
        public static XElement GetKeePassNode <T>(string name, T tData, KdbxSerializationParameters kdbxParams)
        {
            XElement element = new XElement(name);

            if (tData == null)
            {
                return(element);
            }

            string strValue;
            Type   tType = typeof(T);
            object data  = (object)tData;

            if (tType == typeof(Color?) || tType == typeof(Color))
            {
                strValue = ToKeePassColor((Color?)data);
            }
            else if (tType == typeof(bool?) || tType == typeof(bool))
            {
                strValue = ToKeePassBool((bool?)data);
            }
            else if (tType == typeof(DateTime?) || tType == typeof(DateTime))
            {
                strValue = ToKeePassDate((DateTime?)data, kdbxParams);
            }
            else
            {
                strValue = data.ToString();
            }

            if (!string.IsNullOrEmpty(strValue))
            {
                element.SetValue(strValue);
            }
            return(element);
        }
示例#11
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");
 }
示例#12
0
        /// <summary>
        /// Decodes an instance from serialized XML.
        /// </summary>
        /// <param name="xml">The XML to deserialize.</param>
        /// <param name="parameters">Parameters controlling serialization.</param>
        public KdbxBinary(XElement xml, KdbxSerializationParameters parameters)
        {
            // Parse out int ID attribute
            string idAttr = xml?.Attribute("ID")?.Value;

            if (idAttr == null)
            {
                throw new KdbxParseException(
                          ReaderResult.FromXmlParseFailure($"KdbxBinary was missing required ID attribute")
                          );
            }

            if (!Int32.TryParse(idAttr, out int id))
            {
                throw new KdbxParseException(
                          ReaderResult.FromXmlParseFailure($"KdbxBinary ID attribute could not be parsed into an int")
                          );
            }

            Id = id;

            // Parse out bool Compressed attribute
            string compressAttr = xml?.Attribute("Compressed")?.Value ?? "false";

            if (!Boolean.TryParse(compressAttr, out bool compressed))
            {
                throw new KdbxParseException(
                          ReaderResult.FromXmlParseFailure($"KdbxBinary Compressed attribute could not be parsed into a bool")
                          );
            }

            // Parse base64-encoded content
            byte[] content;
            try
            {
                content = CryptographicBuffer.DecodeFromBase64String(xml?.Value)?.ToArray();
                if (content == null)
                {
                    content = new byte[0];
                }
            }
            catch (Exception)
            {
                throw new KdbxParseException(
                          ReaderResult.FromXmlParseFailure($"Could not decode KdbxBinary content as base64 data")
                          );
            }

            // Decompress content if needed
            if (compressed && content.Length > 0)
            {
                byte[] decompressed;
                using (Stream memStream = new MemoryStream(content))
                {
                    using (Stream gzipStream = new GZipStream(memStream, CompressionMode.Decompress))
                    {
                        byte[]      buffer = new byte[1024];
                        int         read   = gzipStream.Read(buffer, 0, buffer.Length);
                        List <byte> bytes  = new List <byte>();
                        while (read > 0)
                        {
                            bytes.AddRange(buffer.Take(read));
                            read = gzipStream.Read(buffer, 0, buffer.Length);
                        }

                        decompressed = bytes.ToArray();
                    }
                }

                content = decompressed;
            }

            this.binaryData = new ProtectedBinary(content, false);
        }
示例#13
0
        /// <summary>
        /// Sets attributes and encoded base64 data, compressed if needed.
        /// </summary>
        /// <param name="xml">The Binary node to populate with attributes and a value.</param>
        /// <param name="rng">Not used.</param>
        /// <param name="parameters">Parameters for serialization.</param>
        public override void PopulateChildren(XElement xml, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
        {
            xml.Add(new XAttribute("ID", Id));

            byte[] data = BinaryData.GetClearData();
            if (ShouldCompress(parameters))
            {
                xml.Add(new XAttribute("Compressed", ToKeePassBool(true)));

                // Compress data if needed
                if (data.Length > 0)
                {
                    using (MemoryStream memStream = new MemoryStream())
                    {
                        using (Stream gzipStream = new GZipStream(memStream, CompressionMode.Compress))
                        {
                            gzipStream.Write(data, 0, data.Length);
                        }

                        memStream.Flush();
                        data = memStream.ToArray();
                    }
                }
            }

            string encoded = CryptographicBuffer.EncodeToBase64String(data.AsBuffer());

            xml.SetValue(encoded);
        }
示例#14
0
 /// <summary>
 /// Helper to get a value for <see cref="Compressed"/> based on serialization parameters.
 /// </summary>
 /// <param name="parameters">Parameters to evaluate.</param>
 /// <returns>Whether this object should use GZip compression when serializing.</returns>
 public static bool ShouldCompress(KdbxSerializationParameters parameters)
 {
     return(parameters?.Compression != CompressionAlgorithm.None);
 }
示例#15
0
        public override void PopulateChildren(XElement xml, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
        {
            xml.Add(GetKeePassNode("Generator", Generator, parameters));
            if (parameters.UseXmlHeaderAuthentication && HeaderHash != null)
            {
                xml.Add(GetKeePassNode("HeaderHash", HeaderHash, parameters));
            }

            xml.Add(
                GetKeePassNode("DatabaseName", DatabaseName, parameters),
                GetKeePassNode("DatabaseNameChanged", DatabaseNameChanged, parameters),
                GetKeePassNode("DatabaseDescription", DatabaseDescription, parameters),
                GetKeePassNode("DatabaseDescriptionChanged", DatabaseDescriptionChanged, parameters),
                GetKeePassNode("DefaultUserName", DefaultUserName, parameters),
                GetKeePassNode("DefaultUserNameChanged", DefaultUserNameChanged, parameters),
                GetKeePassNode("MaintenanceHistoryDays", MaintenanceHistoryDays, parameters),
                GetKeePassNode("Color", DbColor, parameters),
                GetKeePassNode("MasterKeyChanged", MasterKeyChanged, parameters),
                GetKeePassNode("MasterKeyChangeRec", MasterKeyChangeRec, parameters),
                GetKeePassNode("MasterKeyChangeForce", MasterKeyChangeForce, parameters),
                MemoryProtection.ToXml(rng, parameters)
                );

            if (CustomIcons != null)
            {
                xml.Add(CustomIcons.ToXml(rng, parameters));
            }

            xml.Add(
                GetKeePassNode("RecycleBinEnabled", RecycleBinEnabled, parameters),
                GetKeePassNode("RecycleBinUUID", RecycleBinUuid, parameters),
                GetKeePassNode("RecycleBinChanged", RecycleBinChanged, parameters),
                GetKeePassNode("EntryTemplatesGroup", EntryTemplatesGroup, parameters),
                GetKeePassNode("EntryTemplatesGroupChanged", EntryTemplatesGroupChanged, parameters),
                GetKeePassNode("HistoryMaxItems", HistoryMaxItems, parameters),
                GetKeePassNode("HistoryMaxSize", HistoryMaxSize, parameters),
                GetKeePassNode("LastSelectedGroup", LastSelectedGroup, parameters),
                GetKeePassNode("LastTopVisibleGroup", LastTopVisibleGroup, parameters)
                );

            // Only both writing this node if we have binaries (compat issue with KeePass)
            if (parameters.BinariesInXml && Binaries != null && Binaries.Binaries.Any())
            {
                xml.Add(Binaries.ToXml(rng, parameters));
            }

            if (CustomData != null)
            {
                xml.Add(CustomData.ToXml(rng, parameters));
            }
        }
示例#16
0
 public override void PopulateChildren(XElement xml, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
 {
     xml.Add(
         new XElement("ProtectTitle", ToKeePassBool(ProtectTitle)),
         new XElement("ProtectUserName", ToKeePassBool(ProtectUserName)),
         new XElement("ProtectPassword", ToKeePassBool(ProtectPassword)),
         new XElement("ProtectURL", ToKeePassBool(ProtectUrl)),
         new XElement("ProtectNotes", ToKeePassBool(ProtectNotes))
         );
 }
示例#17
0
        public override void PopulateChildren(XElement xml, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
        {
            xml.Add(new XElement("Key", Key));

            XElement valueElement = new XElement("Value");

            if (!string.IsNullOrEmpty(RawValue))
            {
                string value = (Protected ?
                                getEncrypted(ClearValue, rng.GetBytes((uint)this._xorKey.Length)) :
                                ClearValue
                                );
                valueElement.SetValue(value);
            }
            xml.Add(valueElement);

            if (Protected)
            {
                valueElement.SetAttributeValue("Protected", "True");
            }
        }
示例#18
0
 /// <summary>
 /// Given an <see cref="XElement"/> that is currently being constructed for serialization purposes,
 /// populates the children of the element.
 /// </summary>
 /// <param name="xml">The node being populated.</param>
 /// <param name="rng">Random number generator used for serializing protected strings.</param>
 /// <param name="parameters">Parameters controlling serialization.</param>
 public abstract void PopulateChildren(XElement xml, IRandomNumberGenerator rng, KdbxSerializationParameters parameters);
示例#19
0
        public override void PopulateChildren(XElement xml, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
        {
            xml.Add(
                GetKeePassNode("UUID", Uuid, parameters),
                GetKeePassNode("Name", Title.ClearValue, parameters),
                GetKeePassNode("Notes", Notes.ClearValue, parameters),
                GetKeePassNode("IconID", IconID, parameters)
                );

            if (CustomIconUuid != null)
            {
                xml.Add(GetKeePassNode("CustomIconUUID", CustomIconUuid, parameters));
            }

            xml.Add(
                Times.ToXml(rng, parameters),
                GetKeePassNode("IsExpanded", IsExpanded, parameters),
                GetKeePassNode("DefaultAutoTypeSequence", DefaultAutoTypeSequence, parameters),
                GetBizarroNullableBool("EnableAutoType", EnableAutoType, parameters),
                GetBizarroNullableBool("EnableSearching", EnableSearching, parameters),
                GetKeePassNode("LastTopVisibleEntry", LastTopVisibleEntry, parameters)
                );

            foreach (IKeePassNode child in Children)
            {
                xml.Add(child.ToXml(rng, parameters));
            }

            if (CustomData != null)
            {
                xml.Add(CustomData.ToXml(rng, parameters));
            }
        }
示例#20
0
 public override void PopulateChildren(XElement xml, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
 {
     xml.Add(Metadata.ToXml(rng, parameters), Root.ToXml(rng, parameters));
 }
示例#21
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);
        }
示例#22
0
 /// <summary>
 /// Appends the data children to the XML node being serialized.
 /// </summary>
 /// <param name="xml"></param>
 /// <param name="rng"></param>
 /// <param name="parameters"></param>
 public override void PopulateChildren(XElement xml, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
 {
     foreach (KeyValuePair <string, string> kvp in this.data)
     {
         xml.Add(
             new XElement("Item",
                          new XElement("Key", kvp.Key),
                          new XElement("Value", kvp.Value)
                          )
             );
     }
 }
示例#23
0
 public override void PopulateChildren(XElement xml, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
 {
     xml.Add(DatabaseGroup.ToXml(rng, parameters));
     if (this.deletedObjs != null)
     {
         xml.Add(this.deletedObjs);
     }
 }
示例#24
0
        /// <summary>
        /// Populates the given <see cref="XElement"/> with <see cref="KdbxBinary"/> children,
        /// with new IDs based on the current state of this instance.
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="rng"></param>
        /// <param name="parameters"></param>
        public override void PopulateChildren(XElement xml, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
        {
            int i = 0;

            foreach (KeyValuePair <int, KdbxBinary> kvp in this.binaries)
            {
                xml.Add(kvp.Value.With(id: i++).ToXml(rng, parameters));
            }
        }
示例#25
0
 /// <summary>
 /// Not implemented.
 /// </summary>
 /// <param name="rng"></param>
 /// <returns></returns>
 public XElement ToXml(IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
 {
     throw new NotImplementedException();
 }
示例#26
0
        /// <summary>
        /// Parses out a metadata element from XML.
        /// </summary>
        /// <param name="xml">XML to deserialize.</param>
        /// <param name="headerBinaries">Binaries that have been pre-parsed from a header.</param>
        /// <param name="parameters">Parameters controlling serialization.</param>
        public KdbxMetadata(XElement xml, IEnumerable <ProtectedBinary> headerBinaries, KdbxSerializationParameters parameters)
            : base(xml)
        {
            if (headerBinaries == null)
            {
                throw new ArgumentNullException(nameof(headerBinaries));
            }

            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            Generator                  = GetString("Generator");
            HeaderHash                 = GetString("HeaderHash");
            DatabaseName               = GetString("DatabaseName");
            DatabaseNameChanged        = GetDate("DatabaseNameChanged", parameters);
            DatabaseDescription        = GetString("DatabaseDescription");
            DatabaseDescriptionChanged = GetDate("DatabaseDescriptionChanged", parameters);
            DefaultUserName            = GetString("DefaultUserName");
            DefaultUserNameChanged     = GetDate("DefaultUserNameChanged", parameters);
            MaintenanceHistoryDays     = GetInt("MaintenanceHistoryDays");
            DbColor              = GetNullableColor("Color");
            MasterKeyChanged     = GetDate("MasterKeyChanged", parameters, false);
            MasterKeyChangeRec   = GetInt("MasterKeyChangeRec", -1);
            MasterKeyChangeForce = GetInt("MasterKeyChangeForce", -1);
            MemoryProtection     = new KdbxMemoryProtection(GetNode(KdbxMemoryProtection.RootName));

            XElement iconsElement = GetNode(KdbxCustomIcons.RootName);

            if (iconsElement != null)
            {
                CustomIcons = new KdbxCustomIcons(iconsElement);
            }
            else
            {
                CustomIcons = null;
            }

            RecycleBinEnabled          = GetBool("RecycleBinEnabled");
            RecycleBinUuid             = GetUuid("RecycleBinUUID");
            RecycleBinChanged          = GetDate("RecycleBinChanged", parameters);
            EntryTemplatesGroup        = GetUuid("EntryTemplatesGroup");
            EntryTemplatesGroupChanged = GetDate("EntryTemplatesGroupChanged", parameters);
            HistoryMaxItems            = GetInt("HistoryMaxItems", -1);
            HistoryMaxSize             = GetInt("HistoryMaxSize", -1);
            LastSelectedGroup          = GetUuid("LastSelectedGroup");
            LastTopVisibleGroup        = GetUuid("LastTopVisibleGroup");

            XElement binariesElement = GetNode(KdbxBinaries.RootName);

            if (parameters.BinariesInXml)
            {
                if (binariesElement != null)
                {
                    Binaries = new KdbxBinaries(binariesElement, parameters);
                }
                else
                {
                    Binaries = new KdbxBinaries();
                }
            }
            else
            {
                // Populate with values from binary inner header
                Binaries = new KdbxBinaries(headerBinaries);
            }

            XElement customDataElement = GetNode(KdbxCustomData.RootName);

            if (customDataElement != null)
            {
                CustomData = new KdbxCustomData(customDataElement);
            }
            else
            {
                CustomData = null;
            }
        }
示例#27
0
 public override void PopulateChildren(XElement element, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
 {
 }
示例#28
0
 public override void PopulateChildren(XElement xml, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
 {
     xml.Add(
         GetKeePassNode("LastModificationTime", LastModificationTime, parameters),
         GetKeePassNode("CreationTime", CreationTime, parameters),
         GetKeePassNode("LastAccessTime", LastAccessTime, parameters),
         GetKeePassNode("ExpiryTime", ExpiryTime, parameters),
         GetKeePassNode("Expires", Expires, parameters),
         GetKeePassNode("UsageCount", UsageCount, parameters),
         GetKeePassNode("LocationChanged", LocationChanged, parameters)
         );
 }
示例#29
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);
            }
        }
示例#30
0
        /// <summary>
        /// Looks up the data represented by this attachment in the metadata binary collection
        /// to obtain a new @Ref ID for XML serialization.
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="rng"></param>
        /// <param name="parameters"></param>
        public override void PopulateChildren(XElement xml, IRandomNumberGenerator rng, KdbxSerializationParameters parameters)
        {
            int  refId    = 0;
            bool foundBin = false;

            foreach (var bin in this.binaryCollection.Binaries)
            {
                if (bin.Equals(Data))
                {
                    foundBin = true;
                    break;
                }

                refId++;
            }

            DebugHelper.Assert(foundBin);

            xml.Add(
                new XElement("Key", FileName),
                new XElement("Value", new XAttribute("Ref", refId))
                );
        }