From 188687413fafe9853948669979f86b87560fe2db Mon Sep 17 00:00:00 2001 From: Fridrich Štrba Date: Mon, 24 Jun 2013 15:24:19 +0200 Subject: Some more work on the SDW header --- inc/libsdw/SDWDocument.h | 2 +- src/conv/html/sdw2html.cpp | 2 +- src/conv/raw/sdw2raw.cpp | 2 +- src/conv/text/sdw2text.cpp | 2 +- src/lib/Makefile.am | 3 ++ src/lib/SDWDocument.cpp | 9 ++++- src/lib/SDWEncryption.cpp | 56 +++++++++++++++++++++++++++++ src/lib/SDWEncryption.h | 41 +++++++++++++++++++++ src/lib/SDWFileStructure.h | 26 ++++++++++++++ src/lib/SDWHeader.cpp | 88 ++++++++++++++++++++++++++++++++------------- src/lib/SDWHeader.h | 65 ++++++++++----------------------- src/lib/libsdw_internal.cpp | 9 +++++ src/lib/libsdw_internal.h | 2 ++ 13 files changed, 232 insertions(+), 75 deletions(-) create mode 100644 src/lib/SDWEncryption.cpp create mode 100644 src/lib/SDWEncryption.h create mode 100644 src/lib/SDWFileStructure.h diff --git a/inc/libsdw/SDWDocument.h b/inc/libsdw/SDWDocument.h index 26e11e4..7bde26f 100644 --- a/inc/libsdw/SDWDocument.h +++ b/inc/libsdw/SDWDocument.h @@ -44,7 +44,7 @@ StarWriter documents. class SDWDocument { public: - static SDWConfidence isFileFormatSupported(WPXInputStream *input); + static SDWConfidence isFileFormatSupported(WPXInputStream *input, const char *password); static bool verifyPassword(WPXInputStream *input, const char *password); static bool parse(WPXInputStream *input, WPXDocumentInterface *documentInterface, const char *password); }; diff --git a/src/conv/html/sdw2html.cpp b/src/conv/html/sdw2html.cpp index 9c81e5b..9330a71 100644 --- a/src/conv/html/sdw2html.cpp +++ b/src/conv/html/sdw2html.cpp @@ -88,7 +88,7 @@ int main(int argc, char *argv[]) WPXFileStream input(file); - SDWConfidence confidence = SDWDocument::isFileFormatSupported(&input); + SDWConfidence confidence = SDWDocument::isFileFormatSupported(&input, password); if (confidence != SDW_CONFIDENCE_EXCELLENT && confidence != SDW_CONFIDENCE_ENCRYPTION) { fprintf(stderr, "ERROR: Unsupported file format!\n"); diff --git a/src/conv/raw/sdw2raw.cpp b/src/conv/raw/sdw2raw.cpp index 8b97ba9..8cdc723 100644 --- a/src/conv/raw/sdw2raw.cpp +++ b/src/conv/raw/sdw2raw.cpp @@ -92,7 +92,7 @@ int main(int argc, char *argv[]) WPXFileStream input(file); - SDWConfidence confidence = SDWDocument::isFileFormatSupported(&input); + SDWConfidence confidence = SDWDocument::isFileFormatSupported(&input, password); if (confidence != SDW_CONFIDENCE_EXCELLENT && confidence != SDW_CONFIDENCE_ENCRYPTION) { fprintf(stderr, "ERROR: Unsupported file format!\n"); diff --git a/src/conv/text/sdw2text.cpp b/src/conv/text/sdw2text.cpp index dbdd189..389827a 100644 --- a/src/conv/text/sdw2text.cpp +++ b/src/conv/text/sdw2text.cpp @@ -92,7 +92,7 @@ int main(int argc, char *argv[]) WPXFileStream input(szInputFile); - SDWConfidence confidence = SDWDocument::isFileFormatSupported(&input); + SDWConfidence confidence = SDWDocument::isFileFormatSupported(&input, password); if (confidence != SDW_CONFIDENCE_EXCELLENT && confidence != SDW_CONFIDENCE_ENCRYPTION) { fprintf(stderr, "ERROR: Unsupported file format!\n"); diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 5d2e8fd..0417416 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -18,9 +18,12 @@ libsdw_@SDW_MAJOR_VERSION@_@SDW_MINOR_VERSION@_la_LDFLAGS = $(version_info) -exp libsdw_@SDW_MAJOR_VERSION@_@SDW_MINOR_VERSION@_la_SOURCES = \ libsdw_internal.cpp \ SDWDocument.cpp \ + SDWEncryption.cpp \ SDWHeader.cpp \ SDWParser.cpp \ libsdw_internal.h \ + SDWEncryption.h \ + SDWFileStructure.h \ SDWHeader.h \ SDWParser.h diff --git a/src/lib/SDWDocument.cpp b/src/lib/SDWDocument.cpp index 757d5da..695ce8f 100644 --- a/src/lib/SDWDocument.cpp +++ b/src/lib/SDWDocument.cpp @@ -49,7 +49,7 @@ Analyzes the content of an input stream to see if it can be parsed \return A confidence value which represents the likelyhood that the content from the input stream can be parsed */ -libsdw::SDWConfidence libsdw::SDWDocument::isFileFormatSupported(WPXInputStream *input) +libsdw::SDWConfidence libsdw::SDWDocument::isFileFormatSupported(WPXInputStream *input, const char *password) { SDW_DEBUG_MSG(("SDWDocument::isFileFormatSupported()\n")); if (!input->isOLEStream()) @@ -58,6 +58,13 @@ libsdw::SDWConfidence libsdw::SDWDocument::isFileFormatSupported(WPXInputStream if (!starWriterDocument) return SDW_CONFIDENCE_NONE; + SDWHeader header(starWriterDocument, password); + if (!header.isValid()) + { + delete starWriterDocument; + return SDW_CONFIDENCE_NONE; + } + delete starWriterDocument; return SDW_CONFIDENCE_NONE; } diff --git a/src/lib/SDWEncryption.cpp b/src/lib/SDWEncryption.cpp new file mode 100644 index 0000000..b0a2d7c --- /dev/null +++ b/src/lib/SDWEncryption.cpp @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* libwpd + * Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Major Contributor(s): + * Copyright (C) 2007 Fridrich Strba (fridrich.strba@bluewin.ch) + * + * For minor contributions see the git repository. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + * + * For further information visit http://libwpd.sourceforge.net + */ + +/* "This product is not manufactured, approved, or supported by + * Corel Corporation or Corel Corporation Limited." + */ + +#include "SDWEncryption.h" +#include "libsdw_internal.h" +#include + +libsdw::SDWEncryption::SDWEncryption(const char *password) : + m_buffer(NULL), + m_password(password) +{ +} + +libsdw::SDWEncryption::~SDWEncryption() +{ + if (m_buffer) + delete [] m_buffer; +} + +bool libsdw::SDWEncryption::verifyPassword(const uint8_t * /* filePass */, uint32_t /* date */, uint32_t /* time */) +{ + return false; +} + + +const unsigned char *libsdw::SDWEncryption::decrypt(const unsigned char *cryptBuffer, unsigned long numBytes) +{ + if (m_password.len() <= 0) + return cryptBuffer; + (void)numBytes; + + return 0; +} +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff --git a/src/lib/SDWEncryption.h b/src/lib/SDWEncryption.h new file mode 100644 index 0000000..99aa592 --- /dev/null +++ b/src/lib/SDWEncryption.h @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + */ + +#ifndef SDWENCRYPTION_H +#define SDWENCRYPTION_H + +#include +#include "libsdw_internal.h" + +namespace libsdw { + +class SDWEncryption +{ +public: + SDWEncryption(const char *password); + ~SDWEncryption(); + bool verifyPassword(const uint8_t *filePass, uint32_t date, uint32_t time); + const unsigned char *decrypt(const unsigned char *cryptBuffer, unsigned long numBytes); + +private: + unsigned char *m_buffer; + WPXString m_password; + // Unimplemented to prevent compiler from creating crasher ones + SDWEncryption(const SDWEncryption &); + SDWEncryption &operator=(const SDWEncryption &); +}; + +} // namespace libsdw + +#endif /* SDWENCRYPTION_H */ +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff --git a/src/lib/SDWFileStructure.h b/src/lib/SDWFileStructure.h new file mode 100644 index 0000000..3fead57 --- /dev/null +++ b/src/lib/SDWFileStructure.h @@ -0,0 +1,26 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* Version: MPL 2.0 / LGPLv2.1+ + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Alternatively, the contents of this file may be used under the terms + * of the GNU Lesser General Public License Version 2.1 or later + * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are + * applicable instead of those above. + */ + +#ifndef SDWFILESTRUCTURE_H +#define SDWFILESTRUCTURE_H + +#define SWGF_BLOCKNAME 0x0002 +#define SWGF_HAS_PASSWD 0x0008 +#define SWGF_BAD_FILE 0x8000 + +#define SWG_LONGIDX 0x0201 +#define SWG_MAJORVERSION_50 (SWG_LONGIDX) + + +#endif /* SDWFILESTRUCTURE_H */ +/* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff --git a/src/lib/SDWHeader.cpp b/src/lib/SDWHeader.cpp index 7f5509c..be1409b 100644 --- a/src/lib/SDWHeader.cpp +++ b/src/lib/SDWHeader.cpp @@ -1,50 +1,90 @@ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* libwpd - * Version: MPL 2.0 / LGPLv2.1+ +/* Version: MPL 2.0 / LGPLv2.1+ * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Major Contributor(s): - * Copyright (C) 2002 William Lachance (wrlach@gmail.com) - * Copyright (C) 2002-2004 Marc Maurer (uwog@uwog.net) - * - * For minor contributions see the git repository. - * * Alternatively, the contents of this file may be used under the terms * of the GNU Lesser General Public License Version 2.1 or later * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are * applicable instead of those above. - * - * For further information visit http://libwpd.sourceforge.net - */ - -/* "This product is not manufactured, approved, or supported by - * Corel Corporation or Corel Corporation Limited." */ #include "SDWHeader.h" +#include "SDWEncryption.h" +#include "SDWFileStructure.h" #include -libsdw::SDWHeader::SDWHeader(WPXInputStream * /* input */, SDWEncryption * /* encryption */, uint32_t documentOffset, uint8_t productType, - uint8_t fileType, uint8_t majorVersion, uint8_t minorVersion, uint16_t documentEncryption) : - m_documentOffset(documentOffset), - m_productType(productType), - m_fileType(fileType), - m_majorVersion(majorVersion), - m_minorVersion(minorVersion), - m_documentEncryption(documentEncryption) +libsdw::SDWHeader::SDWHeader(WPXInputStream *input, const char *password) : + m_needsPassword(false), + m_validHeader(false), + m_encryption(0) { + m_validHeader = loadHeader(input, password); } libsdw::SDWHeader::~SDWHeader() { } -libsdw::SDWHeader *libsdw::SDWHeader::constructHeader(WPXInputStream * /* input */, SDWEncryption * /* encryption */) +bool libsdw::SDWHeader::loadHeader(WPXInputStream *input, const char *password) { - return 0; + WPXString signature = readString(input); + SDW_DEBUG_MSG(("SDWHeader signature %s\n", signature.cstr())); + if (signature != "SW3HDR" && signature != "SW4HDR" && signature != "SW5HDR") + return false; + + uint8_t cLen = readU8(input); + long oldOffset = input->tell(); + + uint16_t version = readU16(input); + uint16_t fileFlags = readU16(input); + if (fileFlags & SWGF_BAD_FILE) // Error on write + return false; + if (fileFlags & SWGF_HAS_PASSWD) + m_needsPassword = true; + input->seek(4, WPX_SEEK_CUR); // int32_t docFlags = readS32(input); + input->seek(4, WPX_SEEK_CUR); // uint32_t recSzPos = readU32(input); + input->seek(6, WPX_SEEK_CUR); + input->seek(1, WPX_SEEK_CUR); // uint8_t redlineMode = readU8(input); + uint8_t compatVer = readU8(input); + if (version >= SWG_MAJORVERSION_50 && compatVer > 0) + return false; + + unsigned long numBytesRead(0L); + const uint8_t *passwd = input->read(16L, numBytesRead); + if (!passwd || numBytesRead != 16L) + return false; + + input->seek(1, WPX_SEEK_CUR); // uint8_t charSet = readU8(input); + input->seek(1, WPX_SEEK_CUR); // uint8_t gui = readU8(input); + + uint32_t date = readU32(input); + uint32_t time = readU32(input); + + WPXString blockName; + if (fileFlags & SWGF_BLOCKNAME) + { + const uint8_t *buffer = input->read(64L, numBytesRead); + if (numBytesRead != 64L && buffer[63] != 0) + return false; + blockName.append((const char*)buffer); + SDW_DEBUG_MSG(("SDWHeader blockName \"%s\"\n", blockName.cstr())); + } + + SDW_DEBUG_MSG(("SDWHeader finished construction\n")); + input->seek(oldOffset + cLen, WPX_SEEK_SET); + + if (m_needsPassword && password) + m_encryption = new SDWEncryption(password); + if (m_encryption && !m_encryption->verifyPassword(passwd, date, time)) + { + delete m_encryption; + m_encryption = 0; + return false; + } + return true; } /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff --git a/src/lib/SDWHeader.h b/src/lib/SDWHeader.h index c1e7c62..4455357 100644 --- a/src/lib/SDWHeader.h +++ b/src/lib/SDWHeader.h @@ -1,31 +1,18 @@ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* libwpd - * Version: MPL 2.0 / LGPLv2.1+ +/* Version: MPL 2.0 / LGPLv2.1+ * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * - * Major Contributor(s): - * Copyright (C) 2002 William Lachance (wrlach@gmail.com) - * Copyright (C) 2002-2003 Marc Maurer (uwog@uwog.net) - * - * For minor contributions see the git repository. - * * Alternatively, the contents of this file may be used under the terms * of the GNU Lesser General Public License Version 2.1 or later * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are * applicable instead of those above. - * - * For further information visit http://libwpd.sourceforge.net - */ - -/* "This product is not manufactured, approved, or supported by - * Corel Corporation or Corel Corporation Limited." */ -#ifndef WPXHEADER_H -#define WPXHEADER_H +#ifndef SDWHEADER_H +#define SDWHEADER_H #include #include @@ -39,47 +26,33 @@ class SDWEncryption; class SDWHeader { public: - SDWHeader(WPXInputStream *input, SDWEncryption *encryption, uint32_t documentOffset, uint8_t productType, - uint8_t fileType, uint8_t majorVersion, uint8_t minorVersion, uint16_t documentEncryption); + SDWHeader(WPXInputStream *input, const char *password); virtual ~SDWHeader(); - - static SDWHeader *constructHeader(WPXInputStream *input, SDWEncryption *encryption); - - uint32_t getDocumentOffset() const + + bool isValid() { - return m_documentOffset; + return m_validHeader; } - uint8_t getProductType() const + + bool needsPassword() { - return m_productType; + return m_needsPassword; } - uint8_t getFileType() const - { - return m_fileType; - } - uint8_t getMajorVersion() const - { - return m_majorVersion; - } - uint8_t getMinorVersion() const - { - return m_minorVersion; - } - uint16_t getDocumentEncryption() const + + SDWEncryption *getEncryption() const { - return m_documentEncryption; + return m_encryption; } private: - uint32_t m_documentOffset; - uint8_t m_productType; - uint8_t m_fileType; - uint8_t m_majorVersion; - uint8_t m_minorVersion; - uint16_t m_documentEncryption; + bool m_needsPassword; + bool m_validHeader; + SDWEncryption *m_encryption; + + bool loadHeader(WPXInputStream *input, const char *password); }; } // namespace libsdw -#endif /* WPXHEADER_H */ +#endif /* SDWHEADER_H */ /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff --git a/src/lib/libsdw_internal.cpp b/src/lib/libsdw_internal.cpp index bfdc6ed..e4e4c52 100644 --- a/src/lib/libsdw_internal.cpp +++ b/src/lib/libsdw_internal.cpp @@ -85,4 +85,13 @@ int32_t libsdw::readS32(WPXInputStream *input) return (int32_t)readU32(input); } +WPXString libsdw::readString(WPXInputStream *input) +{ + WPXString text; + uint8_t c = 0; + while ( !input->atEOS() && (c = readU8(input)) ) + text.append((char)c); + return text; +} + /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ diff --git a/src/lib/libsdw_internal.h b/src/lib/libsdw_internal.h index 4a2af91..729c941 100644 --- a/src/lib/libsdw_internal.h +++ b/src/lib/libsdw_internal.h @@ -113,6 +113,8 @@ uint32_t readU32(WPXInputStream *input); int8_t readS8(WPXInputStream *input); int16_t readS16(WPXInputStream *input); int32_t readS32(WPXInputStream *input); + +WPXString readString(WPXInputStream *input); } // namespace libsdw #endif /* LIBSDW_INTERNAL_H */ -- cgit v1.2.3