/*********************************************************************************************************************************** Decompress data ***********************************************************************************************************************************/ static Buffer * testDecompress(IoFilter *decompress, Buffer *compressed, size_t inputSize, size_t outputSize) { Buffer *decompressed = bufNew(1024 * 1024); Buffer *output = bufNew(outputSize); ioBufferSizeSet(inputSize); IoFilterGroup *filterGroup = ioFilterGroupNew(); ioFilterGroupAdd(filterGroup, decompress); IoRead *read = ioBufferReadNew(compressed); ioReadFilterGroupSet(read, filterGroup); ioReadOpen(read); while (!ioReadEof(read)) { ioRead(read, output); bufCat(decompressed, output); bufUsedZero(output); } ioReadClose(read); bufFree(output); memContextFree(((GzipDecompress *)ioFilterDriver(decompress))->memContext); return decompressed; }
/*********************************************************************************************************************************** Read all IO into a buffer ***********************************************************************************************************************************/ Buffer * ioReadBuf(IoRead *read) { FUNCTION_TEST_BEGIN(); FUNCTION_TEST_PARAM(IO_READ, read); FUNCTION_TEST_END(); ASSERT(read != NULL); Buffer *result = NULL; MEM_CONTEXT_TEMP_BEGIN() { // Read IO into the buffer result = bufNew(0); do { bufResize(result, bufSize(result) + ioBufferSize()); ioRead(read, result); } while (!ioReadEof(read)); // Resize the buffer and move to calling context bufResize(result, bufUsed(result)); bufMove(result, MEM_CONTEXT_OLD()); } MEM_CONTEXT_TEMP_END(); FUNCTION_TEST_RETURN(result); }
/*********************************************************************************************************************************** Test Run ***********************************************************************************************************************************/ void testRun(void) { FUNCTION_HARNESS_VOID(); // Additional coverage not provided by testing with actual certificates // ***************************************************************************************************************************** if (testBegin("asn1ToStr(), tlsClientHostVerify(), and tlsClientHostVerifyName()")) { TEST_ERROR(asn1ToStr(NULL), CryptoError, "TLS certificate name entry is missing"); TEST_ERROR( tlsClientHostVerifyName( strNew("host"), strNewN("ab\0cd", 5)), CryptoError, "TLS certificate name contains embedded null"); TEST_ERROR(tlsClientHostVerify(strNew("host"), NULL), CryptoError, "No certificate presented by the TLS server"); TEST_RESULT_BOOL(tlsClientHostVerifyName(strNew("host"), strNew("**")), false, "invalid pattern"); TEST_RESULT_BOOL(tlsClientHostVerifyName(strNew("host"), strNew("*.")), false, "invalid pattern"); TEST_RESULT_BOOL(tlsClientHostVerifyName(strNew("a.bogus.host.com"), strNew("*.host.com")), false, "invalid host"); } // ***************************************************************************************************************************** if (testBegin("TlsClient verification")) { TlsClient *client = NULL; // Connection errors // ------------------------------------------------------------------------------------------------------------------------- TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), 9443, 0, true, NULL, NULL), "new client"); TEST_ERROR( tlsClientOpen(client), HostConnectError, "unable to get address for '99.99.99.99.99': [-2] Name or service not known"); TEST_ASSIGN(client, tlsClientNew(strNew("localhost"), 9443, 100, true, NULL, NULL), "new client"); TEST_ERROR(tlsClientOpen(client), HostConnectError, "unable to connect to 'localhost:9443': [111] Connection refused"); // Certificate location and validation errors // ------------------------------------------------------------------------------------------------------------------------- // Add test hosts if (system( // {uncoverable_branch} "echo \"127.0.0.1 test.pgbackrest.org host.test2.pgbackrest.org test3.pgbackrest.org\" |" " sudo tee -a /etc/hosts > /dev/null") != 0) { THROW(AssertError, "unable to add test hosts to /etc/hosts"); // {uncovered+} } // Start server to test various certificate errors testTlsServerAltName(); TEST_ERROR( tlsClientOpen(tlsClientNew(strNew("localhost"), 9443, 500, true, strNew("bogus.crt"), strNew("/bogus"))), CryptoError, "unable to set user-defined CA certificate location: [33558530] No such file or directory"); TEST_ERROR( tlsClientOpen(tlsClientNew(strNew("localhost"), 9443, 500, true, NULL, strNew("/bogus"))), CryptoError, "unable to verify certificate presented by 'localhost:9443': [20] unable to get local issuer certificate"); TEST_RESULT_VOID( tlsClientOpen( tlsClientNew(strNew("test.pgbackrest.org"), 9443, 500, true, strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)), "success on valid ca file and match common name"); TEST_RESULT_VOID( tlsClientOpen( tlsClientNew(strNew("host.test2.pgbackrest.org"), 9443, 500, true, strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)), "success on valid ca file and match alt name"); TEST_ERROR( tlsClientOpen( tlsClientNew(strNew("test3.pgbackrest.org"), 9443, 500, true, strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)), CryptoError, "unable to find hostname 'test3.pgbackrest.org' in certificate common name or subject alternative names"); TEST_ERROR( tlsClientOpen( tlsClientNew(strNew("localhost"), 9443, 500, true, strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".crt", testRepoPath()), NULL)), CryptoError, "unable to verify certificate presented by 'localhost:9443': [20] unable to get local issuer certificate"); TEST_RESULT_VOID( tlsClientOpen(tlsClientNew(strNew("localhost"), 9443, 500, false, NULL, NULL)), "success on no verify"); } // ***************************************************************************************************************************** if (testBegin("TlsClient general usage")) { TlsClient *client = NULL; // Reset statistics tlsClientStatLocal = (TlsClientStat){0}; TEST_RESULT_STR(tlsClientStatStr(), NULL, "no stats yet"); testTlsServer(); ioBufferSizeSet(12); TEST_ASSIGN(client, tlsClientNew(strNew(TLS_TEST_HOST), 9443, 500, true, NULL, NULL), "new client"); TEST_RESULT_VOID(tlsClientOpen(client), "open client"); const Buffer *input = BUFSTRDEF("some protocol info"); TEST_RESULT_VOID(ioWrite(tlsClientIoWrite(client), input), "write input"); ioWriteFlush(tlsClientIoWrite(client)); TEST_RESULT_STR(strPtr(ioReadLine(tlsClientIoRead(client))), "something:0", "read line"); TEST_RESULT_BOOL(ioReadEof(tlsClientIoRead(client)), false, " check eof = false"); Buffer *output = bufNew(12); TEST_RESULT_INT(ioRead(tlsClientIoRead(client), output), 12, "read output"); TEST_RESULT_STR(strPtr(strNewBuf(output)), "some content", " check output"); TEST_RESULT_BOOL(ioReadEof(tlsClientIoRead(client)), false, " check eof = false"); output = bufNew(8); TEST_RESULT_INT(ioRead(tlsClientIoRead(client), output), 8, "read output"); TEST_RESULT_STR(strPtr(strNewBuf(output)), "AND MORE", " check output"); TEST_RESULT_BOOL(ioReadEof(tlsClientIoRead(client)), false, " check eof = false"); output = bufNew(12); TEST_ERROR( ioRead(tlsClientIoRead(client), output), FileReadError, "unable to read data from 'tls.test.pgbackrest.org:9443' after 500ms"); // ------------------------------------------------------------------------------------------------------------------------- input = BUFSTRDEF("more protocol info"); TEST_RESULT_VOID(tlsClientOpen(client), "open client again (it is already open)"); TEST_RESULT_VOID(ioWrite(tlsClientIoWrite(client), input), "write input"); ioWriteFlush(tlsClientIoWrite(client)); output = bufNew(12); TEST_RESULT_INT(ioRead(tlsClientIoRead(client), output), 12, "read output"); TEST_RESULT_STR(strPtr(strNewBuf(output)), "0123456789AB", " check output"); TEST_RESULT_BOOL(ioReadEof(tlsClientIoRead(client)), false, " check eof = false"); output = bufNew(12); TEST_RESULT_INT(ioRead(tlsClientIoRead(client), output), 0, "read no output after eof"); TEST_RESULT_BOOL(ioReadEof(tlsClientIoRead(client)), true, " check eof = true"); TEST_RESULT_BOOL(tlsClientStatStr() != NULL, true, "check statistics exist"); TEST_RESULT_VOID(tlsClientFree(client), "free client"); } FUNCTION_HARNESS_RESULT_VOID(); }