diff --git a/doc/xml/release.xml b/doc/xml/release.xml index ddfb0693c..54b679460 100644 --- a/doc/xml/release.xml +++ b/doc/xml/release.xml @@ -35,6 +35,10 @@

Add interface objects for libxml2.

+ +

Add encryption capability to Info* objects.

+
+

Add IoFilter interface to CipherBlock object.

diff --git a/src/Makefile b/src/Makefile index 85844011b..3fee1689a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -165,7 +165,7 @@ install: pgbackrest command/archive/common.o: command/archive/common.c command/archive/common.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h postgres/version.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h $(CC) $(CFLAGS) -c command/archive/common.c -o command/archive/common.o -command/archive/get/file.o: command/archive/get/file.c command/archive/common.h command/archive/get/file.h command/control/control.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h compress/gzip.h compress/gzipDecompress.h config/config.auto.h config/config.h config/define.auto.h config/define.h info/infoArchive.h info/infoPg.h postgres/interface.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h +command/archive/get/file.o: command/archive/get/file.c command/archive/common.h command/archive/get/file.h command/control/control.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h compress/gzip.h compress/gzipDecompress.h config/config.auto.h config/config.h config/define.auto.h config/define.h crypto/crypto.h info/infoArchive.h info/infoPg.h postgres/interface.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h $(CC) $(CFLAGS) -c command/archive/get/file.c -o command/archive/get/file.o command/archive/get/get.o: command/archive/get/get.c command/archive/common.h command/archive/get/file.h command/command.h common/assert.h common/debug.h common/error.auto.h common/error.h common/fork.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h postgres/interface.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h @@ -330,13 +330,13 @@ crypto/crypto.o: crypto/crypto.c common/debug.h common/error.auto.h common/error crypto/hash.o: crypto/hash.c common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/filter.intern.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/variant.h common/type/variantList.h crypto/crypto.h crypto/hash.h $(CC) $(CFLAGS) -c crypto/hash.c -o crypto/hash.o -info/info.o: info/info.c common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h crypto/hash.h info/info.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h +info/info.o: info/info.c common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h crypto/cipherBlock.h crypto/crypto.h crypto/hash.h info/info.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h $(CC) $(CFLAGS) -c info/info.c -o info/info.o -info/infoArchive.o: info/infoArchive.c common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h info/infoArchive.h info/infoPg.h postgres/interface.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h +info/infoArchive.o: info/infoArchive.c common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h crypto/crypto.h info/infoArchive.h info/infoPg.h postgres/interface.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h $(CC) $(CFLAGS) -c info/infoArchive.c -o info/infoArchive.o -info/infoPg.o: info/infoPg.c common/assert.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/json.h common/type/keyValue.h common/type/list.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h crypto/hash.h info/info.h info/infoPg.h postgres/interface.h postgres/version.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h +info/infoPg.o: info/infoPg.c common/assert.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/json.h common/type/keyValue.h common/type/list.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h crypto/crypto.h crypto/hash.h info/info.h info/infoPg.h postgres/interface.h postgres/version.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h $(CC) $(CFLAGS) -c info/infoPg.c -o info/infoPg.o main.o: main.c command/archive/get/get.h command/archive/push/push.h command/command.h command/help/help.h common/debug.h common/error.auto.h common/error.h common/exit.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h postgres/interface.h version.h diff --git a/src/command/archive/get/file.c b/src/command/archive/get/file.c index 426e51496..b08f3a177 100644 --- a/src/command/archive/get/file.c +++ b/src/command/archive/get/file.c @@ -10,6 +10,7 @@ Archive Get File #include "compress/gzip.h" #include "compress/gzipDecompress.h" #include "config/config.h" +#include "crypto/crypto.h" #include "info/infoArchive.h" #include "postgres/interface.h" #include "storage/helper.h" @@ -35,7 +36,8 @@ archiveGetCheck(const String *archiveFile) PgControl controlInfo = pgControlFromFile(cfgOptionStr(cfgOptPgPath)); // Attempt to load the archive info file - InfoArchive *info = infoArchiveNew(storageRepo(), STRING_CONST(STORAGE_REPO_ARCHIVE "/" INFO_ARCHIVE_FILE), false); + InfoArchive *info = infoArchiveNew( + storageRepo(), STRING_CONST(STORAGE_REPO_ARCHIVE "/" INFO_ARCHIVE_FILE), false, cipherTypeNone, NULL); // Loop through the pg history in case the WAL we need is not in the most recent archive id String *archiveId = NULL; diff --git a/src/info/info.c b/src/info/info.c index 09628d279..54d73e617 100644 --- a/src/info/info.c +++ b/src/info/info.c @@ -9,6 +9,7 @@ Info Handler #include "common/ini.h" #include "common/log.h" #include "common/memContext.h" +#include "crypto/cipherBlock.h" #include "crypto/hash.h" #include "info/info.h" #include "storage/helper.h" @@ -18,8 +19,14 @@ Info Handler Internal constants ***********************************************************************************************************************************/ #define INI_COPY_EXT ".copy" + #define INI_SECTION_BACKREST "backrest" STRING_STATIC(INI_SECTION_BACKREST_STR, INI_SECTION_BACKREST); +#define INI_SECTION_CIPHER "cipher" + STRING_STATIC(INI_SECTION_CIPHER_STR, INI_SECTION_CIPHER); + +#define INI_KEY_CIPHER_PASS "cipher-pass" + STRING_STATIC(INI_KEY_CIPHER_PASS_STR, INI_KEY_CIPHER_PASS); #define INI_KEY_FORMAT "backrest-format" STRING_STATIC(INI_KEY_FORMAT_STR, INI_KEY_FORMAT); #define INI_KEY_CHECKSUM "backrest-checksum" @@ -33,6 +40,7 @@ struct Info MemContext *memContext; // Context that contains the info String *fileName; // Full path name of the file Ini *ini; // Parsed file contents + const String *cipherPass; // Cipher passphrase if set }; /*********************************************************************************************************************************** @@ -174,14 +182,14 @@ infoValidInternal( Internal function to load the copy and check validity ***********************************************************************************************************************************/ static bool -loadInternal( - Info *this, // Info object to load parsed buffer into - const Storage *storage, - bool copyFile) // Is this the copy file? +loadInternal(Info *this, const Storage *storage, bool copyFile, CipherType cipherType, const String *cipherPass) { - FUNCTION_DEBUG_BEGIN(logLevelTrace); - FUNCTION_DEBUG_PARAM(INFO, this); - FUNCTION_DEBUG_PARAM(BOOL, copyFile); + FUNCTION_DEBUG_BEGIN(logLevelTrace) + FUNCTION_DEBUG_PARAM(INFO, this); // Info object to load parsed buffer into + FUNCTION_DEBUG_PARAM(STORAGE, storage); + FUNCTION_DEBUG_PARAM(BOOL, copyFile); // Is this the copy file? + FUNCTION_DEBUG_PARAM(ENUM, cipherType); + // cipherPass omitted for security FUNCTION_DEBUG_ASSERT(this != NULL); FUNCTION_DEBUG_END(); @@ -193,7 +201,18 @@ loadInternal( String *fileName = copyFile ? strCat(strDup(this->fileName), INI_COPY_EXT) : this->fileName; // Attempt to load the file - Buffer *buffer = storageGetNP(storageNewReadP(storage, fileName, .ignoreMissing = true)); + StorageFileRead *infoRead = storageNewReadP(storage, fileName, .ignoreMissing = true); + + if (cipherType != cipherTypeNone) + { + ioReadFilterGroupSet( + storageFileReadIo(infoRead), + ioFilterGroupAdd( + ioFilterGroupNew(), cipherBlockFilter(cipherBlockNew(cipherModeDecrypt, cipherType, bufNewStr(cipherPass), + NULL)))); + } + + Buffer *buffer = storageGetNP(infoRead); // If the file exists, parse and validate it if (buffer != NULL) @@ -217,12 +236,13 @@ Load an Info object // ??? The file MUST exist currently, so this is not actually creating the object - rather it is loading it ***********************************************************************************************************************************/ Info * -infoNew( - const Storage *storage, - const String *fileName) // Full path/filename to load +infoNew(const Storage *storage, const String *fileName, CipherType cipherType, const String *cipherPass) { FUNCTION_DEBUG_BEGIN(logLevelDebug); - FUNCTION_DEBUG_PARAM(STRING, fileName); + FUNCTION_DEBUG_PARAM(STORAGE, storage); + FUNCTION_DEBUG_PARAM(STRING, fileName); // Full path/filename to load + FUNCTION_DEBUG_PARAM(ENUM, cipherType); + // cipherPass omitted for security FUNCTION_DEBUG_ASSERT(fileName != NULL); FUNCTION_DEBUG_END(); @@ -239,9 +259,9 @@ infoNew( this->fileName = strDup(fileName); // Attempt to load the main file. If it does not exist or is invalid, try to load the copy. - if (!loadInternal(this, storage, false)) + if (!loadInternal(this, storage, false, cipherType, cipherPass)) { - if (!loadInternal(this, storage, true)) + if (!loadInternal(this, storage, true, cipherType, cipherPass)) { THROW_FMT( FileMissingError, "unable to open %s or %s", @@ -249,6 +269,15 @@ infoNew( strPtr(strCat(storagePathNP(storage, this->fileName), INI_COPY_EXT))); } } + + // Load the cipher passphrase if it exists + String *cipherPass = varStr(iniGetDefault(this->ini, INI_SECTION_CIPHER_STR, INI_KEY_CIPHER_PASS_STR, NULL)); + + if (cipherPass != NULL) + { + this->cipherPass = strSubN(cipherPass, 1, strSize(cipherPass) - 2); + strFree(cipherPass); + } } MEM_CONTEXT_NEW_END(); @@ -259,6 +288,18 @@ infoNew( /*********************************************************************************************************************************** Accessor functions ***********************************************************************************************************************************/ +const String * +infoCipherPass(const Info *this) +{ + FUNCTION_TEST_BEGIN(); + FUNCTION_TEST_PARAM(INFO, this); + + FUNCTION_TEST_ASSERT(this != NULL); + FUNCTION_TEST_END(); + + FUNCTION_TEST_RESULT(CONST_STRING, this->cipherPass); +} + Ini * infoIni(const Info *this) { diff --git a/src/info/info.h b/src/info/info.h index bc19a4cdb..fe29e7f19 100644 --- a/src/info/info.h +++ b/src/info/info.h @@ -10,17 +10,19 @@ Object type typedef struct Info Info; #include "common/ini.h" +#include "crypto/crypto.h" #include "crypto/hash.h" #include "storage/storage.h" /*********************************************************************************************************************************** Constructor ***********************************************************************************************************************************/ -Info *infoNew(const Storage *storage, const String *fileName); +Info *infoNew(const Storage *storage, const String *fileName, CipherType cipherType, const String *cipherPass); /*********************************************************************************************************************************** Getters ***********************************************************************************************************************************/ +const String *infoCipherPass(const Info *this); String *infoFileName(const Info *this); Ini *infoIni(const Info *this); diff --git a/src/info/infoArchive.c b/src/info/infoArchive.c index 884919add..ec42f5bad 100644 --- a/src/info/infoArchive.c +++ b/src/info/infoArchive.c @@ -30,11 +30,14 @@ Create a new InfoArchive object // ??? Need loadFile parameter ***********************************************************************************************************************************/ InfoArchive * -infoArchiveNew(const Storage *storage, const String *fileName, bool ignoreMissing) +infoArchiveNew(const Storage *storage, const String *fileName, bool ignoreMissing, CipherType cipherType, const String *cipherPass) { FUNCTION_DEBUG_BEGIN(logLevelDebug); + FUNCTION_DEBUG_PARAM(STORAGE, storage); FUNCTION_DEBUG_PARAM(STRING, fileName); FUNCTION_DEBUG_PARAM(BOOL, ignoreMissing); + FUNCTION_DEBUG_PARAM(ENUM, cipherType); + // cipherPass omitted for security FUNCTION_DEBUG_ASSERT(fileName != NULL); FUNCTION_DEBUG_END(); @@ -50,7 +53,7 @@ infoArchiveNew(const Storage *storage, const String *fileName, bool ignoreMissin // Catch file missing error and add archive-specific hints before rethrowing TRY_BEGIN() { - this->infoPg = infoPgNew(storage, fileName, infoPgArchive); + this->infoPg = infoPgNew(storage, fileName, infoPgArchive, cipherType, cipherPass); } CATCH(FileMissingError) { @@ -132,6 +135,21 @@ infoArchiveId(const InfoArchive *this) FUNCTION_TEST_RESULT(STRING, this->archiveId); } +/*********************************************************************************************************************************** +Return the cipher passphrase +***********************************************************************************************************************************/ +const String * +infoArchiveCipherPass(const InfoArchive *this) +{ + FUNCTION_TEST_BEGIN(); + FUNCTION_TEST_PARAM(INFO_ARCHIVE, this); + + FUNCTION_TEST_ASSERT(this != NULL); + FUNCTION_TEST_END(); + + FUNCTION_TEST_RESULT(CONST_STRING, infoPgCipherPass(this->infoPg)); +} + /*********************************************************************************************************************************** Get PostgreSQL info ***********************************************************************************************************************************/ diff --git a/src/info/infoArchive.h b/src/info/infoArchive.h index a13783aeb..077520d11 100644 --- a/src/info/infoArchive.h +++ b/src/info/infoArchive.h @@ -10,6 +10,7 @@ Object type typedef struct InfoArchive InfoArchive; #include "common/type/string.h" +#include "crypto/crypto.h" #include "info/infoPg.h" #include "storage/storage.h" @@ -21,7 +22,8 @@ Archive info filename /*********************************************************************************************************************************** Constructor ***********************************************************************************************************************************/ -InfoArchive *infoArchiveNew(const Storage *storage, const String *fileName, bool ignoreMissing); +InfoArchive *infoArchiveNew( + const Storage *storage, const String *fileName, bool ignoreMissing, CipherType cipherType, const String *cipherPass); /*********************************************************************************************************************************** Functions @@ -32,6 +34,7 @@ void infoArchiveCheckPg(const InfoArchive *this, unsigned int pgVersion, uint64_ Getters ***********************************************************************************************************************************/ const String *infoArchiveId(const InfoArchive *this); +const String *infoArchiveCipherPass(const InfoArchive *this); InfoPg *infoArchivePg(const InfoArchive *this); /*********************************************************************************************************************************** diff --git a/src/info/infoPg.c b/src/info/infoPg.c index 92e2985d5..3d81141f1 100644 --- a/src/info/infoPg.c +++ b/src/info/infoPg.c @@ -58,10 +58,14 @@ Load an InfoPg object ??? Currently this assumes the file exists and loads data from it ***********************************************************************************************************************************/ InfoPg * -infoPgNew(const Storage *storage, const String *fileName, InfoPgType type) +infoPgNew(const Storage *storage, const String *fileName, InfoPgType type, CipherType cipherType, const String *cipherPass) { FUNCTION_DEBUG_BEGIN(logLevelDebug); + FUNCTION_DEBUG_PARAM(STORAGE, storage); FUNCTION_DEBUG_PARAM(STRING, fileName); + FUNCTION_DEBUG_PARAM(ENUM, type); + FUNCTION_DEBUG_PARAM(ENUM, cipherType); + // cipherPass omitted for security FUNCTION_DEBUG_ASSERT(fileName != NULL); FUNCTION_DEBUG_END(); @@ -73,7 +77,7 @@ infoPgNew(const Storage *storage, const String *fileName, InfoPgType type) // Create object this = memNew(sizeof(InfoPg)); this->memContext = MEM_CONTEXT_NEW(); - this->info = infoNew(storage, fileName); + this->info = infoNew(storage, fileName, cipherType, cipherPass); // Get the pg history list this->history = lstNew(sizeof(InfoPgData)); @@ -171,6 +175,21 @@ infoPgArchiveId(const InfoPg *this, unsigned int pgDataIdx) FUNCTION_DEBUG_RESULT(STRING, strNewFmt("%s-%u", strPtr(pgVersionToStr(pgData.version)), pgData.id)); } +/*********************************************************************************************************************************** +Return the cipher passphrase +***********************************************************************************************************************************/ +const String * +infoPgCipherPass(const InfoPg *this) +{ + FUNCTION_TEST_BEGIN(); + FUNCTION_TEST_PARAM(INFO_PG, this); + + FUNCTION_TEST_ASSERT(this != NULL); + FUNCTION_TEST_END(); + + FUNCTION_TEST_RESULT(CONST_STRING, infoCipherPass(this->info)); +} + /*********************************************************************************************************************************** Return a structure of the Postgres data from a specific index ***********************************************************************************************************************************/ diff --git a/src/info/infoPg.h b/src/info/infoPg.h index d049c9c55..314219364 100644 --- a/src/info/infoPg.h +++ b/src/info/infoPg.h @@ -11,6 +11,7 @@ typedef struct InfoPg InfoPg; #include +#include "crypto/crypto.h" #include "storage/storage.h" /*********************************************************************************************************************************** @@ -38,7 +39,7 @@ typedef enum /*********************************************************************************************************************************** Constructor ***********************************************************************************************************************************/ -InfoPg *infoPgNew(const Storage *storage, const String *fileName, InfoPgType type); +InfoPg *infoPgNew(const Storage *storage, const String *fileName, InfoPgType type, CipherType cipherType, const String *cipherPass); /*********************************************************************************************************************************** Functions @@ -49,7 +50,7 @@ void infoPgAdd(InfoPg *this, const InfoPgData *infoPgData); Getters ***********************************************************************************************************************************/ String *infoPgArchiveId(const InfoPg *this, unsigned int pgDataIdx); - +const String *infoPgCipherPass(const InfoPg *this); InfoPgData infoPgData(const InfoPg *this, unsigned int pgDataIdx); InfoPgData infoPgDataCurrent(const InfoPg *this); unsigned int infoPgDataTotal(const InfoPg *this); diff --git a/test/expect/mock-archive-001.log b/test/expect/mock-archive-001.log index b1a90f6f0..5eaf1b3f7 100644 --- a/test/expect/mock-archive-001.log +++ b/test/expect/mock-archive-001.log @@ -133,9 +133,9 @@ P00 DEBUG: storage/storage::storageGet: => {used: 512, size: 512, limit: {version: 90400, systemId: 1000000000000000094, walSegmentSize: 16777216, pageChecksum: true} P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: (path: {"[TEST_PATH]/db-master/repo"}, modeFile: 0640, modePath: 0750, write: false, pathExpressionFunction: (function *)) P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: => {StorageDriverPosix} -P00 DEBUG: info/infoArchive::infoArchiveNew: (fileName: {"/archive.info"}, ignoreMissing: false) -P00 DEBUG: info/infoPg::infoPgNew: (fileName: {"/archive.info"}) -P00 DEBUG: info/info::infoNew: (fileName: {"/archive.info"}) +P00 DEBUG: info/infoArchive::infoArchiveNew: (storage: {type: posix, path: {"[TEST_PATH]/db-master/repo"}, write: false}, fileName: {"/archive.info"}, ignoreMissing: false, cipherType: 0) +P00 DEBUG: info/infoPg::infoPgNew: (storage: {type: posix, path: {"[TEST_PATH]/db-master/repo"}, write: false}, fileName: {"/archive.info"}, type: 0, cipherType: 0) +P00 DEBUG: info/info::infoNew: (storage: {type: posix, path: {"[TEST_PATH]/db-master/repo"}, write: false}, fileName: {"/archive.info"}, cipherType: 0) P00 DEBUG: info/info::infoNew: => {Info} P00 DEBUG: info/infoPg::infoPgNew: => {InfoPg} P00 DEBUG: info/infoArchive::infoArchiveNew: => {InfoArchive} @@ -175,9 +175,9 @@ P00 DEBUG: storage/storage::storageGet: => {used: 512, size: 512, limit: {version: 90400, systemId: 1000000000000000094, walSegmentSize: 16777216, pageChecksum: true} P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: (path: {"[TEST_PATH]/db-master/repo"}, modeFile: 0640, modePath: 0750, write: false, pathExpressionFunction: (function *)) P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: => {StorageDriverPosix} -P00 DEBUG: info/infoArchive::infoArchiveNew: (fileName: {"/archive.info"}, ignoreMissing: false) -P00 DEBUG: info/infoPg::infoPgNew: (fileName: {"/archive.info"}) -P00 DEBUG: info/info::infoNew: (fileName: {"/archive.info"}) +P00 DEBUG: info/infoArchive::infoArchiveNew: (storage: {type: posix, path: {"[TEST_PATH]/db-master/repo"}, write: false}, fileName: {"/archive.info"}, ignoreMissing: false, cipherType: 0) +P00 DEBUG: info/infoPg::infoPgNew: (storage: {type: posix, path: {"[TEST_PATH]/db-master/repo"}, write: false}, fileName: {"/archive.info"}, type: 0, cipherType: 0) +P00 DEBUG: info/info::infoNew: (storage: {type: posix, path: {"[TEST_PATH]/db-master/repo"}, write: false}, fileName: {"/archive.info"}, cipherType: 0) P00 DEBUG: info/info::infoNew: => {Info} P00 DEBUG: info/infoPg::infoPgNew: => {InfoPg} P00 DEBUG: info/infoArchive::infoArchiveNew: => {InfoArchive} diff --git a/test/expect/mock-stanza-001.log b/test/expect/mock-stanza-001.log index 05c52a375..4a16708c5 100644 --- a/test/expect/mock-stanza-001.log +++ b/test/expect/mock-stanza-001.log @@ -550,9 +550,9 @@ P00 DEBUG: storage/storage::storageGet: => {used: 512, size: 512, limit: {version: 90300, systemId: 1000000000000000093, walSegmentSize: 16777216, pageChecksum: true} P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: (path: {"[TEST_PATH]/db-master/repo"}, modeFile: 0640, modePath: 0750, write: false, pathExpressionFunction: (function *)) P00 DEBUG: storage/driver/posix/storage::storageDriverPosixNew: => {StorageDriverPosix} -P00 DEBUG: info/infoArchive::infoArchiveNew: (fileName: {"/archive.info"}, ignoreMissing: false) -P00 DEBUG: info/infoPg::infoPgNew: (fileName: {"/archive.info"}) -P00 DEBUG: info/info::infoNew: (fileName: {"/archive.info"}) +P00 DEBUG: info/infoArchive::infoArchiveNew: (storage: {type: posix, path: {"[TEST_PATH]/db-master/repo"}, write: false}, fileName: {"/archive.info"}, ignoreMissing: false, cipherType: 0) +P00 DEBUG: info/infoPg::infoPgNew: (storage: {type: posix, path: {"[TEST_PATH]/db-master/repo"}, write: false}, fileName: {"/archive.info"}, type: 0, cipherType: 0) +P00 DEBUG: info/info::infoNew: (storage: {type: posix, path: {"[TEST_PATH]/db-master/repo"}, write: false}, fileName: {"/archive.info"}, cipherType: 0) P00 DEBUG: info/info::infoNew: => {Info} P00 DEBUG: info/infoPg::infoPgNew: => {InfoPg} P00 DEBUG: info/infoArchive::infoArchiveNew: => {InfoArchive} diff --git a/test/src/module/info/infoArchiveTest.c b/test/src/module/info/infoArchiveTest.c index de5ac4ce2..411a62c76 100644 --- a/test/src/module/info/infoArchiveTest.c +++ b/test/src/module/info/infoArchiveTest.c @@ -17,7 +17,7 @@ testRun(void) String *fileName = strNewFmt("%s/test.ini", testPath()); TEST_ERROR_FMT( - infoArchiveNew(storageLocal(), fileName, true), FileMissingError, + infoArchiveNew(storageLocal(), fileName, true, cipherTypeNone, NULL), FileMissingError, "unable to open %s/test.ini or %s/test.ini.copy\n" "HINT: archive.info does not exist but is required to push/get WAL segments.\n" "HINT: is archive_command configured in postgresql.conf?\n" @@ -47,9 +47,10 @@ testRun(void) InfoArchive *info = NULL; - TEST_ASSIGN(info, infoArchiveNew(storageLocal(), fileName, true), " new archive info"); + TEST_ASSIGN(info, infoArchiveNew(storageLocal(), fileName, true, cipherTypeNone, NULL), " new archive info"); TEST_RESULT_STR(strPtr(infoArchiveId(info)), "9.4-1", " archiveId set"); TEST_RESULT_PTR(infoArchivePg(info), info->infoPg, " infoPg set"); + TEST_RESULT_PTR(infoArchiveCipherPass(info), NULL, " no cipher passphrase"); // Check PG version //-------------------------------------------------------------------------------------------------------------------------- diff --git a/test/src/module/info/infoPgTest.c b/test/src/module/info/infoPgTest.c index f80358320..d5482d576 100644 --- a/test/src/module/info/infoPgTest.c +++ b/test/src/module/info/infoPgTest.c @@ -36,7 +36,8 @@ testRun(void) InfoPg *infoPg = NULL; - TEST_ASSIGN(infoPg, infoPgNew(storageLocal(), fileName, infoPgArchive), "new infoPg archive - load file"); + TEST_ASSIGN( + infoPg, infoPgNew(storageLocal(), fileName, infoPgArchive, cipherTypeNone, NULL), "new infoPg archive - load file"); TEST_RESULT_INT(lstSize(infoPg->history), 1, " history record added"); @@ -48,6 +49,7 @@ testRun(void) TEST_RESULT_INT(infoPgData.controlVersion, 0, " control-version not set"); TEST_RESULT_INT(infoPgDataTotal(infoPg), 1, " check pg data total"); TEST_RESULT_STR(strPtr(infoPgArchiveId(infoPg, 0)), "9.4-1", " check pg archive id"); + TEST_RESULT_PTR(infoPgCipherPass(infoPg), NULL, " no cipher passphrase"); // Backup info //-------------------------------------------------------------------------------------------------------------------------- @@ -72,7 +74,8 @@ testRun(void) TEST_RESULT_VOID(storagePutNP(storageNewWriteNP(storageLocalWrite(), fileName), bufNewStr(content)), "put info to file"); - TEST_ASSIGN(infoPg, infoPgNew(storageLocal(), fileName, infoPgBackup), "new infoPg backup - load file"); + TEST_ASSIGN( + infoPg, infoPgNew(storageLocal(), fileName, infoPgBackup, cipherTypeNone, NULL), "new infoPg backup - load file"); TEST_RESULT_INT(lstSize(infoPg->history), 1, " history record added"); @@ -108,7 +111,8 @@ testRun(void) TEST_RESULT_VOID(storagePutNP(storageNewWriteNP(storageLocalWrite(), fileName), bufNewStr(content)), "put info to file"); - TEST_ASSIGN(infoPg, infoPgNew(storageLocal(), fileName, infoPgManifest), "new infoPg manifest - load file"); + TEST_ASSIGN( + infoPg, infoPgNew(storageLocal(), fileName, infoPgManifest, cipherTypeNone, NULL), "new infoPg manifest - load file"); TEST_RESULT_INT(lstSize(infoPg->history), 2, "history record added"); @@ -137,9 +141,10 @@ testRun(void) // Errors //-------------------------------------------------------------------------------------------------------------------------- - TEST_ERROR(infoPgNew(storageLocal(), fileName, 10), AssertError, "invalid InfoPg type 10"); + TEST_ERROR(infoPgNew(storageLocal(), fileName, 10, cipherTypeNone, NULL), AssertError, "invalid InfoPg type 10"); TEST_ERROR( - infoPgNew(storageLocal(), NULL, infoPgManifest), AssertError, "function debug assertion 'fileName != NULL' failed"); + infoPgNew(storageLocal(), NULL, infoPgManifest, cipherTypeNone, NULL), AssertError, + "function debug assertion 'fileName != NULL' failed"); TEST_ERROR(infoPgDataCurrent(NULL), AssertError, "function debug assertion 'this != NULL' failed"); diff --git a/test/src/module/info/infoTest.c b/test/src/module/info/infoTest.c index 998b3136f..50a2f7e50 100644 --- a/test/src/module/info/infoTest.c +++ b/test/src/module/info/infoTest.c @@ -38,27 +38,55 @@ testRun(void) //-------------------------------------------------------------------------------------------------------------------------- String *missingInfoError = strNewFmt("unable to open %s or %s", strPtr(fileName), strPtr(fileNameCopy)); - TEST_ERROR(infoNew(storageLocal(), fileName), FileMissingError, strPtr(missingInfoError)); + TEST_ERROR(infoNew(storageLocal(), fileName, cipherTypeNone, NULL), FileMissingError, strPtr(missingInfoError)); // Only copy exists and one is required //-------------------------------------------------------------------------------------------------------------------------- TEST_RESULT_VOID( storagePutNP(storageNewWriteNP(storageLocalWrite(), fileNameCopy), bufNewStr(content)), "put info.copy to file"); - TEST_ASSIGN(info, infoNew(storageLocal(), fileName), "infoNew() - load copy file"); + TEST_ASSIGN(info, infoNew(storageLocal(), fileName, cipherTypeNone, NULL), "infoNew() - load copy file"); TEST_RESULT_STR(strPtr(infoFileName(info)), strPtr(fileName), " infoFileName() is set"); TEST_RESULT_PTR(infoIni(info), info->ini, " infoIni() returns pointer to info->ini"); + TEST_RESULT_PTR(infoCipherPass(info), NULL, " cipherPass is not set"); - // Remove the copy and store only the main info file. One is required. + // Remove the copy and store only the main info file and encrypt it. One is required. //-------------------------------------------------------------------------------------------------------------------------- - storageMoveNP( - storageLocal(), storageNewReadNP(storageLocal(), fileNameCopy), storageNewWriteNP(storageLocalWrite(), fileName)); + StorageFileWrite *infoWrite = storageNewWriteNP(storageLocalWrite(), fileName); + + ioWriteFilterGroupSet( + storageFileWriteIo(infoWrite), + ioFilterGroupAdd( + ioFilterGroupNew(), + cipherBlockFilter(cipherBlockNew(cipherModeEncrypt, cipherTypeAes256Cbc, bufNewStr(strNew("12345678")), NULL)))); + + storageRemoveNP(storageLocalWrite(), fileNameCopy); + storagePutNP( + infoWrite, + bufNewStr( + strNew( + "[backrest]\n" + "backrest-checksum=\"9d2f6dce339751e1a056187fad67d2834b3d4ab3\"\n" + "backrest-format=5\n" + "backrest-version=\"2.04\"\n" + "\n" + "[cipher]\n" + "cipher-pass=\"ABCDEFGH\"\n" + "\n" + "[db]\n" + "db-id=1\n" + "db-system-id=6569239123849665679\n" + "db-version=\"9.4\"\n" + "\n" + "[db:history]\n" + "1={\"db-id\":6569239123849665679,\"db-version\":\"9.4\"}\n"))); // Only main info exists and is required - TEST_ASSIGN(info, infoNew(storageLocal(), fileName), "infoNew() - load file"); + TEST_ASSIGN(info, infoNew(storageLocal(), fileName, cipherTypeAes256Cbc, strNew("12345678")), "infoNew() - load file"); TEST_RESULT_STR(strPtr(infoFileName(info)), strPtr(fileName), " infoFileName() is set"); + TEST_RESULT_STR(strPtr(infoCipherPass(info)), "ABCDEFGH", " cipherPass is set"); // Invalid format //-------------------------------------------------------------------------------------------------------------------------- @@ -87,7 +115,7 @@ testRun(void) TEST_RESULT_VOID( storagePutNP(storageNewWriteNP(storageLocalWrite(), fileName), bufNewStr(content)), "put invalid br format to file"); - TEST_ERROR(infoNew(storageLocal(), fileName), FileMissingError, strPtr(missingInfoError)); + TEST_ERROR(infoNew(storageLocal(), fileName, cipherTypeNone, NULL), FileMissingError, strPtr(missingInfoError)); harnessLogResult( strPtr( strNewFmt("P00 WARN: invalid format in '%s', expected %d but found %d", strPtr(fileName), REPOSITORY_FORMAT, 4))); @@ -95,7 +123,7 @@ testRun(void) storageCopyNP(storageNewReadNP(storageLocal(), fileName), storageNewWriteNP(storageLocalWrite(), fileNameCopy)); TEST_ERROR( - infoNew(storageLocal(), fileName), FormatError, + infoNew(storageLocal(), fileName, cipherTypeNone, NULL), FormatError, strPtr(strNewFmt("invalid format in '%s', expected %d but found %d", strPtr(fileName), REPOSITORY_FORMAT, 4))); harnessLogResult( strPtr( @@ -150,7 +178,7 @@ testRun(void) // Copy file error TEST_ERROR( - infoNew(storageLocal(), fileName), ChecksumError, + infoNew(storageLocal(), fileName, cipherTypeNone, NULL), ChecksumError, strPtr(strNewFmt("invalid checksum in '%s', expected '%s' but found '%s'", strPtr(fileName), "4306ec205f71417c301e403c4714090e61c8a736", "4306ec205f71417c301e403c4714090e61c8a999")));