Kaydet (Commit) e60506ac authored tarafından Ras-al-Ghul's avatar Ras-al-Ghul Kaydeden (comit) Jan Holesovsky

tdf#98602 Duplicate code in onlineupdate/

Converted libmar into static library and removed duplicated code

Change-Id: I6a6c8ce24103a400e1835ccf7e6421024f5cec4b
Reviewed-on: https://gerrit.libreoffice.org/23179Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarJan Holesovsky <kendy@collabora.com>
üst 60286229
...@@ -11,12 +11,15 @@ $(eval $(call gb_Executable_Executable,mar)) ...@@ -11,12 +11,15 @@ $(eval $(call gb_Executable_Executable,mar))
$(eval $(call gb_Executable_set_include,mar,\ $(eval $(call gb_Executable_set_include,mar,\
-I$(SRCDIR)/onlineupdate/source/libmar/inc/ \ -I$(SRCDIR)/onlineupdate/source/libmar/inc/ \
-I$(SRCDIR)/onlineupdate/source/libmar/src/ \
-I$(SRCDIR)/onlineupdate/source/libmar/verify/ \ -I$(SRCDIR)/onlineupdate/source/libmar/verify/ \
-I$(SRCDIR)/onlineupdate/source/libmar/sign/ \ -I$(SRCDIR)/onlineupdate/source/libmar/sign/ \
$$(INCLUDE) \ $$(INCLUDE) \
)) ))
$(eval $(call gb_Library_use_static_libraries,Executable_mar,\
libmar \
))
ifeq ($(OS),WNT) ifeq ($(OS),WNT)
$(eval $(call gb_Executable_add_libs,mar,\ $(eval $(call gb_Executable_add_libs,mar,\
ws2_32.lib \ ws2_32.lib \
...@@ -30,9 +33,6 @@ $(eval $(call gb_Executable_add_defs,mar,-DMAR_NSS)) ...@@ -30,9 +33,6 @@ $(eval $(call gb_Executable_add_defs,mar,-DMAR_NSS))
endif endif
$(eval $(call gb_Executable_add_cobjects,mar,\ $(eval $(call gb_Executable_add_cobjects,mar,\
onlineupdate/source/libmar/src/mar_create \
onlineupdate/source/libmar/src/mar_extract \
onlineupdate/source/libmar/src/mar_read \
onlineupdate/source/libmar/sign/nss_secutil \ onlineupdate/source/libmar/sign/nss_secutil \
onlineupdate/source/libmar/sign/mar_sign \ onlineupdate/source/libmar/sign/mar_sign \
onlineupdate/source/libmar/verify/cryptox \ onlineupdate/source/libmar/verify/cryptox \
......
...@@ -10,13 +10,16 @@ ...@@ -10,13 +10,16 @@
$(eval $(call gb_Executable_Executable,updater)) $(eval $(call gb_Executable_Executable,updater))
$(eval $(call gb_Executable_set_include,updater,\ $(eval $(call gb_Executable_set_include,updater,\
-I$(SRCDIR)/onlineupdate/source/update/src \
-I$(SRCDIR)/onlineupdate/source/update/inc \ -I$(SRCDIR)/onlineupdate/source/update/inc \
-I$(SRCDIR)/onlineupdate/source/update/common \ -I$(SRCDIR)/onlineupdate/source/update/common \
-I$(SRCDIR)/onlineupdate/source/update/updater/xpcom/glue \ -I$(SRCDIR)/onlineupdate/source/update/updater/xpcom/glue \
$$(INCLUDE) \ $$(INCLUDE) \
)) ))
$(eval $(call gb_Library_use_static_libraries,Executable_updater,\
libmar \
))
ifeq ($(OS),WNT) ifeq ($(OS),WNT)
$(eval $(call gb_Executable_add_libs,updater,\ $(eval $(call gb_Executable_add_libs,updater,\
Ws2_32.lib \ Ws2_32.lib \
...@@ -64,10 +67,4 @@ $(eval $(call gb_Executable_add_exception_objects,updater,\ ...@@ -64,10 +67,4 @@ $(eval $(call gb_Executable_add_exception_objects,updater,\
onlineupdate/source/update/common/updatelogging \ onlineupdate/source/update/common/updatelogging \
)) ))
$(eval $(call gb_Executable_add_cobjects,updater,\
onlineupdate/source/update/src/mar_create \
onlineupdate/source/update/src/mar_extract \
onlineupdate/source/update/src/mar_read \
))
# vim:set shiftwidth=4 tabstop=4 noexpandtab: */ # vim:set shiftwidth=4 tabstop=4 noexpandtab: */
...@@ -14,6 +14,7 @@ ifneq ($(ENABLE_ONLINE_UPDATE_MAR),) ...@@ -14,6 +14,7 @@ ifneq ($(ENABLE_ONLINE_UPDATE_MAR),)
$(eval $(call gb_Module_add_targets,onlineupdate,\ $(eval $(call gb_Module_add_targets,onlineupdate,\
Executable_mar \ Executable_mar \
Executable_updater \ Executable_updater \
StaticLibrary_libmar \
)) ))
endif endif
......
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# 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/.
#
$(eval $(call gb_StaticLibrary_StaticLibrary,libmar))
$(eval $(call gb_StaticLibrary_set_include,libmar,\
-I$(SRCDIR)/onlineupdate/source/libmar/src/ \
$$(INCLUDE) \
))
$(eval $(call gb_StaticLibrary_add_cobjects,libmar,\
onlineupdate/source/libmar/src/mar_create \
onlineupdate/source/libmar/src/mar_extract \
onlineupdate/source/libmar/src/mar_read \
))
# vim:set shiftwidth=4 tabstop=4 noexpandtab: */
# vim:set ts=8 sw=8 sts=8 noet:
#
# 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/.
# This makefile just builds support for reading archives.
include $(topsrcdir)/config/rules.mk
# The intermediate (.ii/.s) files for host and target can have the same name...
# disable parallel builds
.NOTPARALLEL:
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#ifndef MAR_H__
#define MAR_H__
#include "mozilla/Assertions.h"
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* We have a MAX_SIGNATURES limit so that an invalid MAR will never
* waste too much of either updater's or signmar's time.
* It is also used at various places internally and will affect memory usage.
* If you want to increase this value above 9 then you need to adjust parsing
* code in tool/mar.c.
*/
#define MAX_SIGNATURES 8
#ifdef __cplusplus
static_assert(MAX_SIGNATURES <= 9, "too many signatures");
#else
MOZ_STATIC_ASSERT(MAX_SIGNATURES <= 9, "too many signatures");
#endif
struct ProductInformationBlock {
const char *MARChannelID;
const char *productVersion;
};
/**
* The MAR item data structure.
*/
typedef struct MarItem_ {
struct MarItem_ *next; /* private field */
uint32_t offset; /* offset into archive */
uint32_t length; /* length of data in bytes */
uint32_t flags; /* contains file mode bits */
char name[1]; /* file path */
} MarItem;
#define TABLESIZE 256
struct MarFile_ {
FILE *fp;
MarItem *item_table[TABLESIZE];
};
typedef struct MarFile_ MarFile;
/**
* Signature of callback function passed to mar_enum_items.
* @param mar The MAR file being visited.
* @param item The MAR item being visited.
* @param data The data parameter passed by the caller of mar_enum_items.
* @return A non-zero value to stop enumerating.
*/
typedef int (* MarItemCallback)(MarFile *mar, const MarItem *item, void *data);
/**
* Open a MAR file for reading.
* @param path Specifies the path to the MAR file to open. This path must
* be compatible with fopen.
* @return NULL if an error occurs.
*/
MarFile *mar_open(const char *path);
#ifdef _WIN32
MarFile *mar_wopen(const wchar_t *path);
#endif
/**
* Close a MAR file that was opened using mar_open.
* @param mar The MarFile object to close.
*/
void mar_close(MarFile *mar);
/**
* Find an item in the MAR file by name.
* @param mar The MarFile object to query.
* @param item The name of the item to query.
* @return A const reference to a MAR item or NULL if not found.
*/
const MarItem *mar_find_item(MarFile *mar, const char *item);
/**
* Enumerate all MAR items via callback function.
* @param mar The MAR file to enumerate.
* @param callback The function to call for each MAR item.
* @param data A caller specified value that is passed along to the
* callback function.
* @return 0 if the enumeration ran to completion. Otherwise, any
* non-zero return value from the callback is returned.
*/
int mar_enum_items(MarFile *mar, MarItemCallback callback, void *data);
/**
* Read from MAR item at given offset up to bufsize bytes.
* @param mar The MAR file to read.
* @param item The MAR item to read.
* @param offset The byte offset relative to the start of the item.
* @param buf A pointer to a buffer to copy the data into.
* @param bufsize The length of the buffer to copy the data into.
* @return The number of bytes written or a negative value if an
* error occurs.
*/
int mar_read(MarFile *mar, const MarItem *item, int offset, char *buf,
int bufsize);
/**
* Create a MAR file from a set of files.
* @param dest The path to the file to create. This path must be
* compatible with fopen.
* @param numfiles The number of files to store in the archive.
* @param files The list of null-terminated file paths. Each file
* path must be compatible with fopen.
* @param infoBlock The information to store in the product information block.
* @return A non-zero value if an error occurs.
*/
int mar_create(const char *dest,
int numfiles,
char **files,
struct ProductInformationBlock *infoBlock);
/**
* Extract a MAR file to the current working directory.
* @param path The path to the MAR file to extract. This path must be
* compatible with fopen.
* @return A non-zero value if an error occurs.
*/
int mar_extract(const char *path);
#define MAR_MAX_CERT_SIZE (16*1024) // Way larger than necessary
/* Read the entire file (not a MAR file) into a newly-allocated buffer.
* This function does not write to stderr. Instead, the caller should
* write whatever error messages it sees fit. The caller must free the returned
* buffer using free().
*
* @param filePath The path to the file that should be read.
* @param maxSize The maximum valid file size.
* @param data On success, *data will point to a newly-allocated buffer
* with the file's contents in it.
* @param size On success, *size will be the size of the created buffer.
*
* @return 0 on success, -1 on error
*/
int mar_read_entire_file(const char * filePath,
uint32_t maxSize,
/*out*/ const uint8_t * *data,
/*out*/ uint32_t *size);
/**
* Verifies a MAR file by verifying each signature with the corresponding
* certificate. That is, the first signature will be verified using the first
* certificate given, the second signature will be verified using the second
* certificate given, etc. The signature count must exactly match the number of
* certificates given, and all signature verifications must succeed.
* We do not check that the certificate was issued by any trusted authority.
* We assume it to be self-signed. We do not check whether the certificate
* is valid for this usage.
*
* @param mar The already opened MAR file.
* @param certData Pointer to the first element in an array of certificate
* file data.
* @param certDataSizes Pointer to the first element in an array for size of
* the cert data.
* @param certCount The number of elements in certData and certDataSizes
* @return 0 on success
* a negative number if there was an error
* a positive number if the signature does not verify
*/
int mar_verify_signatures(MarFile *mar,
const uint8_t * const *certData,
const uint32_t *certDataSizes,
uint32_t certCount);
/**
* Reads the product info block from the MAR file's additional block section.
* The caller is responsible for freeing the fields in infoBlock
* if the return is successful.
*
* @param infoBlock Out parameter for where to store the result to
* @return 0 on success, -1 on failure
*/
int
mar_read_product_info_block(MarFile *mar,
struct ProductInformationBlock *infoBlock);
#ifdef __cplusplus
}
#endif
#endif /* MAR_H__ */
/* 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/. */
#ifndef MAR_CMDLINE_H__
#define MAR_CMDLINE_H__
/* We use NSPR here just to import the definition of uint32_t */
#ifdef __cplusplus
extern "C" {
#endif
struct ProductInformationBlock;
/**
* Determines MAR file information.
*
* @param path The path of the MAR file to check.
* @param hasSignatureBlock Optional out parameter specifying if the MAR
* file has a signature block or not.
* @param numSignatures Optional out parameter for storing the number
* of signatures in the MAR file.
* @param hasAdditionalBlocks Optional out parameter specifying if the MAR
* file has additional blocks or not.
* @param offsetAdditionalBlocks Optional out parameter for the offset to the
* first additional block. Value is only valid if
* hasAdditionalBlocks is not equal to 0.
* @param numAdditionalBlocks Optional out parameter for the number of
* additional blocks. Value is only valid if
* has_additional_blocks is not equal to 0.
* @return 0 on success and non-zero on failure.
*/
int get_mar_file_info(const char *path,
int *hasSignatureBlock,
uint32_t *numSignatures,
int *hasAdditionalBlocks,
uint32_t *offsetAdditionalBlocks,
uint32_t *numAdditionalBlocks);
/**
* Reads the product info block from the MAR file's additional block section.
* The caller is responsible for freeing the fields in infoBlock
* if the return is successful.
*
* @param infoBlock Out parameter for where to store the result to
* @return 0 on success, -1 on failure
*/
int
read_product_info_block(char *path,
struct ProductInformationBlock *infoBlock);
/**
* Refreshes the product information block with the new information.
* The input MAR must not be signed or the function call will fail.
*
* @param path The path to the MAR file whose product info block
* should be refreshed.
* @param infoBlock Out parameter for where to store the result to
* @return 0 on success, -1 on failure
*/
int
refresh_product_info_block(const char *path,
struct ProductInformationBlock *infoBlock);
/**
* Writes out a copy of the MAR at src but with the signature block stripped.
*
* @param src The path of the source MAR file
* @param dest The path of the MAR file to write out that
has no signature block
* @return 0 on success
* -1 on error
*/
int
strip_signature_block(const char *src, const char * dest);
/**
* Extracts a signature from a MAR file, base64 encodes it, and writes it out
*
* @param src The path of the source MAR file
* @param sigIndex The index of the signature to extract
* @param dest The path of file to write the signature to
* @return 0 on success
* -1 on error
*/
int
extract_signature(const char *src, uint32_t sigIndex, const char * dest);
/**
* Imports a base64 encoded signature into a MAR file
*
* @param src The path of the source MAR file
* @param sigIndex The index of the signature to import
* @param base64SigFile A file which contains the signature to import
* @param dest The path of the destination MAR file with replaced signature
* @return 0 on success
* -1 on error
*/
int
import_signature(const char *src,
uint32_t sigIndex,
const char * base64SigFile,
const char *dest);
#ifdef __cplusplus
}
#endif
#endif /* MAR_CMDLINE_H__ */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "mar_private.h"
#include "mar.h"
#ifdef _WIN32
#include <io.h>
#include <direct.h>
#endif
/* Ensure that the directory containing this file exists */
static int mar_ensure_parent_dir(const char *path)
{
char *slash = strrchr(path, '/');
if (slash)
{
*slash = '\0';
mar_ensure_parent_dir(path);
#ifdef _WIN32
_mkdir(path);
#else
mkdir(path, 0755);
#endif
*slash = '/';
}
return 0;
}
static int mar_test_callback(MarFile *mar, const MarItem *item, void *unused) {
FILE *fp;
char buf[BLOCKSIZE];
int fd, len, offset = 0;
(void) unused; // avoid warnings
if (mar_ensure_parent_dir(item->name))
return -1;
#ifdef _WIN32
fd = _open(item->name, _O_BINARY|_O_CREAT|_O_TRUNC|_O_WRONLY, item->flags);
#else
fd = creat(item->name, item->flags);
#endif
if (fd == -1) {
fprintf(stderr, "ERROR: could not create file in mar_test_callback()\n");
perror(item->name);
return -1;
}
fp = fdopen(fd, "wb");
if (!fp)
return -1;
while ((len = mar_read(mar, item, offset, buf, sizeof(buf))) > 0) {
if (fwrite(buf, len, 1, fp) != 1)
break;
offset += len;
}
fclose(fp);
return len == 0 ? 0 : -1;
}
int mar_extract(const char *path) {
MarFile *mar;
int rv;
mar = mar_open(path);
if (!mar)
return -1;
rv = mar_enum_items(mar, mar_test_callback, NULL);
mar_close(mar);
return rv;
}
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#ifndef MAR_PRIVATE_H__
#define MAR_PRIVATE_H__
#include "limits.h"
#include "mozilla/Assertions.h"
#include <stdint.h>
#define BLOCKSIZE 4096
#define ROUND_UP(n, incr) (((n) / (incr) + 1) * (incr))
#define MAR_ID "MAR1"
#define MAR_ID_SIZE 4
/* The signature block comes directly after the header block
which is 16 bytes */
#define SIGNATURE_BLOCK_OFFSET 16
/* Make sure the file is less than 500MB. We do this to protect against
invalid MAR files. */
#define MAX_SIZE_OF_MAR_FILE ((int64_t)524288000)
/* Existing code makes assumptions that the file size is
smaller than LONG_MAX. */
MOZ_STATIC_ASSERT(MAX_SIZE_OF_MAR_FILE < ((int64_t)LONG_MAX),
"max mar file size is too big");
/* We store at most the size up to the signature block + 4
bytes per BLOCKSIZE bytes */
MOZ_STATIC_ASSERT(sizeof(BLOCKSIZE) < \
(SIGNATURE_BLOCK_OFFSET + sizeof(uint32_t)),
"BLOCKSIZE is too big");
/* The maximum size of any signature supported by current and future
implementations of the signmar program. */
#define MAX_SIGNATURE_LENGTH 2048
/* Each additional block has a unique ID.
The product information block has an ID of 1. */
#define PRODUCT_INFO_BLOCK_ID 1
#define MAR_ITEM_SIZE(namelen) (3*sizeof(uint32_t) + (namelen) + 1)
/* Product Information Block (PIB) constants */
#define PIB_MAX_MAR_CHANNEL_ID_SIZE 63
#define PIB_MAX_PRODUCT_VERSION_SIZE 31
/* The mar program is compiled as a host bin so we don't have access to NSPR at
runtime. For that reason we use ntohl, htonl, and define HOST_TO_NETWORK64
instead of the NSPR equivalents. */
#ifdef _WIN32
#include <winsock2.h>
#define ftello _ftelli64
#define fseeko _fseeki64
#else
#define _FILE_OFFSET_BITS 64
#include <netinet/in.h>
#include <unistd.h>
#endif
#include <stdio.h>
#define HOST_TO_NETWORK64(x) ( \
((((uint64_t) x) & 0xFF) << 56) | \
((((uint64_t) x) >> 8) & 0xFF) << 48) | \
(((((uint64_t) x) >> 16) & 0xFF) << 40) | \
(((((uint64_t) x) >> 24) & 0xFF) << 32) | \
(((((uint64_t) x) >> 32) & 0xFF) << 24) | \
(((((uint64_t) x) >> 40) & 0xFF) << 16) | \
(((((uint64_t) x) >> 48) & 0xFF) << 8) | \
(((uint64_t) x) >> 56)
#define NETWORK_TO_HOST64 HOST_TO_NETWORK64
#endif /* MAR_PRIVATE_H__ */
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment