/** * Tries to parse the given file as a KeePass XML key file. * @param string $filename The name of the file to parse. * @return boolean Returns true in case of success, false otherwise. */ private function tryParseXML($filename) { $xml = new XMLStackReader(); if (!$xml->open($filename)) { return false; } $parents = array(self::XML_ROOT, self::XML_KEY, self::XML_DATA); if ($xml->readUntilParentsBe($parents)) { if ($xml->isTextInside()) { $this->hash = base64_decode($xml->r->value); $xml->close(); return true; } } $xml->close(); return false; }
/** * Tries to parse the given string $xmlsource, assumed to be data formatted * in XML, with the format of a KeePass 2.x database. Returns true * if the parsing succeeds, or false otherwise ; in case of success, * the attribute $this->entries will contain the result of the parsing, * as an array of entries. * @param string $xmlsource * @return boolean */ private function tryXMLParse($xmlsource) { $xml = new XMLStackReader(); if (!$xml->XML($xmlsource)) { $xml->close(); return false; } if (!$xml->read() || $xml->r->name != self::XML_FILEROOT) { $xml->close(); return false; } $expectedParentsMeta = array(self::XML_FILEROOT, self::XML_META); if (!$xml->readUntilParentsBe($expectedParentsMeta)) { $xml->close(); return false; } $isHeaderChecked = false; $d = $xml->r->depth; while ($xml->isInSubtree($d)) { if ($xml->r->name == self::XML_HEADERHASH) { $hash = base64_decode($this->readTextValueFromXML($xml)); if (strcmp($hash, $this->header->headerHash) != 0) { KeePassPHP::printDebug("Bad HeaderHash !"); } $isHeaderChecked = true; } elseif ($xml->r->name == self::XML_CUSTOMICONS) { foreach ($xml->readInnerXML($xml->r->depth) as $icon) { $uuid = null; $data = null; if ($icon[XMLStackReader::NODENAME] == self::XML_ICON && $this->tryReadTextValueFromArray($icon[XMLStackReader::INNER], self::XML_UUID, $uuid) && $this->tryReadTextValueFromArray($icon[XMLStackReader::INNER], self::XML_ICON_DATA, $data)) { $this->icons->addIcon($uuid, $data); } } } } if (!$isHeaderChecked) { KeePassPHP::printDebug("Did not found HeaderHash text node..."); } $this->rawEntries = array(); $expectedParents = array(self::XML_GROUP, self::XML_ENTRY); while ($xml->readUntilParentsBe($expectedParents)) { $entry = array(); $d = $xml->r->depth; while ($xml->isInSubtree($d)) { if ($xml->r->name == self::XML_UUID) { $entry[self::XML_UUID] = bin2hex(base64_decode($this->readTextValueFromXML($xml))); } elseif ($xml->r->name == self::XML_CUSTOMICONUUID) { $entry[self::XML_CUSTOMICONUUID] = $this->readTextValueFromXML($xml); } elseif ($xml->r->name == self::XML_TAGS) { $entry[self::XML_TAGS] = $this->readTextValueFromXML($xml); } elseif ($xml->r->name == self::XML_STRING) { $key = null; $value = null; $isHistory = $xml->isAncestor(self::XML_HISTORY); $inner = $xml->readInnerXML($xml->r->depth); if ($this->tryReadTextValueFromArray($inner, self::XML_STRING_VALUE, $value) && $this->tryReadTextValueFromArray($inner, self::XML_STRING_KEY, $key)) { if ($key != null && $value != null && !$isHistory) { $entry[$key] = $value; } } } } if (count($entry) > 0) { array_push($this->rawEntries, $entry); } } $xml->close(); return true; }