1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-01-18 04:58:51 +02:00

Optional parameters for tlsClientNew().

There are a number of optional parameters with the same type so this makes them easier to track and reduces churn when new ones are added.
This commit is contained in:
David Steele 2021-11-04 08:19:18 -04:00
parent 038abaa71d
commit 676b9d95dd
10 changed files with 96 additions and 92 deletions

View File

@ -30,9 +30,8 @@ cmdServerPing(void)
// Connect to server without any verification
const TimeMSec timeout = cfgOptionUInt64(cfgOptIoTimeout);
IoClient *const tlsClient = tlsClientNew(
sckClientNew(host, cfgOptionUInt(cfgOptTlsServerPort), timeout, timeout), host, timeout, timeout, false, NULL, NULL,
NULL, NULL);
IoClient *const tlsClient = tlsClientNewP(
sckClientNew(host, cfgOptionUInt(cfgOptTlsServerPort), timeout, timeout), host, timeout, timeout, false);
IoSession *const tlsSession = ioClientOpen(tlsClient);
// Send ping

View File

@ -1,7 +1,7 @@
/***********************************************************************************************************************************
Io Client Interface
Create sessions for protocol clients. For example, a TLS client can be created with tlsClientNew() and then new TLS sessions can be
Create sessions for protocol clients. For example, a TLS client can be created with tlsClientNewP() and then new TLS sessions can be
opened with ioClientOpen().
***********************************************************************************************************************************/
#ifndef COMMON_IO_CLIENT_H

View File

@ -348,8 +348,7 @@ static const IoClientInterface tlsClientInterface =
IoClient *
tlsClientNew(
IoClient *const ioClient, const String *const host, const TimeMSec timeoutConnect, const TimeMSec timeoutSession,
const bool verifyPeer, const String *const caFile, const String *const caPath, const String *const certFile,
const String *const keyFile)
const bool verifyPeer, const TlsClientNewParam param)
{
FUNCTION_LOG_BEGIN(logLevelDebug);
FUNCTION_LOG_PARAM(IO_CLIENT, ioClient);
@ -357,10 +356,10 @@ tlsClientNew(
FUNCTION_LOG_PARAM(TIME_MSEC, timeoutConnect);
FUNCTION_LOG_PARAM(TIME_MSEC, timeoutSession);
FUNCTION_LOG_PARAM(BOOL, verifyPeer);
FUNCTION_LOG_PARAM(STRING, caFile);
FUNCTION_LOG_PARAM(STRING, caPath);
FUNCTION_LOG_PARAM(STRING, certFile);
FUNCTION_LOG_PARAM(STRING, keyFile);
FUNCTION_LOG_PARAM(STRING, param.caFile);
FUNCTION_LOG_PARAM(STRING, param.caPath);
FUNCTION_LOG_PARAM(STRING, param.certFile);
FUNCTION_LOG_PARAM(STRING, param.keyFile);
FUNCTION_LOG_END();
ASSERT(ioClient != NULL);
@ -391,10 +390,11 @@ tlsClientNew(
if (driver->verifyPeer)
{
// If the user specified a location
if (caFile != NULL || caPath != NULL) // {vm_covered}
if (param.caFile != NULL || param.caPath != NULL) // {vm_covered}
{
cryptoError( // {vm_covered}
SSL_CTX_load_verify_locations(driver->context, strZNull(caFile), strZNull(caPath)) != 1, // {vm_covered}
SSL_CTX_load_verify_locations( // {vm_covered}
driver->context, strZNull(param.caFile), strZNull(param.caPath)) != 1, // {vm_covered}
"unable to set user-defined CA certificate location"); // {vm_covered}
}
// Else use the defaults
@ -406,7 +406,7 @@ tlsClientNew(
}
// Load certificate and key, if specified
tlsCertKeyLoad(driver->context, certFile, keyFile);
tlsCertKeyLoad(driver->context, param.certFile, param.keyFile);
// Increment stat
statInc(TLS_STAT_CLIENT_STR);

View File

@ -30,9 +30,21 @@ Statistics constants
/***********************************************************************************************************************************
Constructors
***********************************************************************************************************************************/
typedef struct TlsClientNewParam
{
VAR_PARAM_HEADER;
const String *caFile;
const String *caPath;
const String *certFile;
const String *keyFile;
} TlsClientNewParam;
#define tlsClientNewP(ioClient, host, timeoutConnect, timeoutSession, verifyPeer, ...) \
tlsClientNew(ioClient, host, timeoutConnect, timeoutSession, verifyPeer, (TlsClientNewParam){VAR_PARAM_INIT, __VA_ARGS__})
IoClient *tlsClientNew(
IoClient *ioClient, const String *host, TimeMSec timeoutConnect, TimeMSec timeoutSession, bool verifyPeer, const String *caFile,
const String *caPath, const String *certFile, const String *keyFile);
IoClient *ioClient, const String *host, TimeMSec timeoutConnect, TimeMSec timeoutSession, bool verifyPeer,
TlsClientNewParam param);
/***********************************************************************************************************************************
Functions

View File

@ -669,15 +669,15 @@ protocolRemoteExec(
ASSERT(remoteType == CFGOPTVAL_REPO_HOST_TYPE_TLS);
// Negotiate TLS
helper->ioClient = tlsClientNew(
helper->ioClient = tlsClientNewP(
sckClientNew(
host, cfgOptionIdxUInt(isRepo ? cfgOptRepoHostPort : cfgOptPgHostPort, hostIdx),
cfgOptionUInt64(cfgOptIoTimeout), cfgOptionUInt64(cfgOptProtocolTimeout)),
host, cfgOptionUInt64(cfgOptIoTimeout), cfgOptionUInt64(cfgOptProtocolTimeout), true,
cfgOptionIdxStrNull(isRepo ? cfgOptRepoHostCaFile : cfgOptPgHostCaFile, hostIdx),
cfgOptionIdxStrNull(isRepo ? cfgOptRepoHostCaPath : cfgOptPgHostCaPath, hostIdx),
cfgOptionIdxStr(isRepo ? cfgOptRepoHostCertFile : cfgOptPgHostCertFile, hostIdx),
cfgOptionIdxStr(isRepo ? cfgOptRepoHostKeyFile : cfgOptPgHostKeyFile, hostIdx));
.caFile = cfgOptionIdxStrNull(isRepo ? cfgOptRepoHostCaFile : cfgOptPgHostCaFile, hostIdx),
.caPath = cfgOptionIdxStrNull(isRepo ? cfgOptRepoHostCaPath : cfgOptPgHostCaPath, hostIdx),
.certFile = cfgOptionIdxStr(isRepo ? cfgOptRepoHostCertFile : cfgOptPgHostCertFile, hostIdx),
.keyFile = cfgOptionIdxStr(isRepo ? cfgOptRepoHostKeyFile : cfgOptPgHostKeyFile, hostIdx));
helper->ioSession = ioClientOpen(helper->ioClient);
read = ioSessionIoRead(helper->ioSession);

View File

@ -737,9 +737,9 @@ storageAzureNew(
// Create the http client used to service requests
driver->httpClient = httpClientNew(
tlsClientNew(
sckClientNew(driver->host, port, timeout, timeout), driver->host, timeout, timeout, verifyPeer, caFile, caPath,
NULL, NULL),
tlsClientNewP(
sckClientNew(driver->host, port, timeout, timeout), driver->host, timeout, timeout, verifyPeer, .caFile = caFile,
.caPath = caPath),
timeout);
// Create list of redacted headers

View File

@ -973,9 +973,9 @@ storageGcsNew(
driver->authUrl = httpUrlNewParseP(uri, .type = httpProtocolTypeHttps);
driver->authClient = httpClientNew(
tlsClientNew(
tlsClientNewP(
sckClientNew(httpUrlHost(driver->authUrl), httpUrlPort(driver->authUrl), timeout, timeout),
httpUrlHost(driver->authUrl), timeout, timeout, verifyPeer, caFile, caPath, NULL, NULL),
httpUrlHost(driver->authUrl), timeout, timeout, verifyPeer, .caFile = caFile, .caPath = caPath),
timeout);
break;
@ -993,9 +993,9 @@ storageGcsNew(
// Create the http client used to service requests
driver->httpClient = httpClientNew(
tlsClientNew(
tlsClientNewP(
sckClientNew(driver->endpoint, httpUrlPort(url), timeout, timeout), driver->endpoint, timeout, timeout, verifyPeer,
caFile, caPath, NULL, NULL),
.caFile = caFile, .caPath = caPath),
timeout);
// Create list of redacted headers

View File

@ -1077,8 +1077,8 @@ storageS3New(
host = driver->bucketEndpoint;
driver->httpClient = httpClientNew(
tlsClientNew(
sckClientNew(host, port, timeout, timeout), host, timeout, timeout, verifyPeer, caFile, caPath, NULL, NULL),
tlsClientNewP(
sckClientNew(host, port, timeout, timeout), host, timeout, timeout, verifyPeer, .caFile = caFile, .caPath = caPath),
timeout);
// Initialize authentication
@ -1110,9 +1110,9 @@ storageS3New(
driver->credHost = S3_STS_HOST_STR;
driver->credExpirationTime = time(NULL);
driver->credHttpClient = httpClientNew(
tlsClientNew(
tlsClientNewP(
sckClientNew(driver->credHost, S3_STS_PORT, timeout, timeout), driver->credHost, timeout, timeout, true,
caFile, caPath, NULL, NULL),
.caFile = caFile, .caPath = caPath),
timeout);
break;

View File

@ -338,17 +338,13 @@ testRun(void)
// Connection errors
// -------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN(
client,
tlsClientNew(sckClientNew(STRDEF("99.99.99.99.99"), 7777, 0, 0), STRDEF("X"), 0, 0, true, NULL, NULL, NULL, NULL),
"new client");
client, tlsClientNewP(sckClientNew(STRDEF("99.99.99.99.99"), 7777, 0, 0), STRDEF("X"), 0, 0, true), "new client");
TEST_RESULT_STR_Z(ioClientName(client), "99.99.99.99.99:7777", " check name");
TEST_ERROR(
ioClientOpen(client), HostConnectError, "unable to get address for '99.99.99.99.99': [-2] Name or service not known");
TEST_ASSIGN(
client,
tlsClientNew(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 100, 100), STRDEF("X"), 100, 100, true, NULL, NULL, NULL, NULL),
client, tlsClientNewP(sckClientNew(STRDEF("localhost"), hrnServerPort(0), 100, 100), STRDEF("X"), 100, 100, true),
"new client");
TEST_ERROR_FMT(
ioClientOpen(client), HostConnectError, "unable to connect to 'localhost:%u': [111] Connection refused",
@ -359,9 +355,9 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNew(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, STRDEF("bogus.crt"),
STRDEF("/bogus"), NULL, NULL)),
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
.caFile = STRDEF("bogus.crt"), .caPath = STRDEF("/bogus"))),
CryptoError, "unable to set user-defined CA certificate location: [33558530] No such file or directory");
// -------------------------------------------------------------------------------------------------------------------------
@ -369,9 +365,9 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNew(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
STRDEF("/bogus"), STRDEF("/bogus"))),
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF("/bogus"), .keyFile = STRDEF("/bogus"))),
CryptoError, "unable to load cert file '/bogus': [33558530] No such file or directory");
// -------------------------------------------------------------------------------------------------------------------------
@ -379,9 +375,9 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNew(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF("/bogus"))),
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF("/bogus"))),
CryptoError, "unable to load key file '/bogus': [33558530] No such file or directory");
// -------------------------------------------------------------------------------------------------------------------------
@ -389,9 +385,9 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNew(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(HRN_SERVER_KEY))),
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(HRN_SERVER_KEY))),
CryptoError,
"unable to load key file '" HRN_PATH_REPO "/test/certificate/pgbackrest-test-server.key': [185073780] key values"
" mismatch");
@ -404,17 +400,17 @@ testRun(void)
TRY_BEGIN()
{
TEST_ERROR(
tlsClientNew(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(TEST_PATH "/client-pwd.key")),
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(TEST_PATH "/client-pwd.key")),
CryptoError, "unable to load key file '" TEST_PATH "/client-pwd.key': [101077092] bad decrypt");
}
CATCH(TestError)
{
TEST_ERROR( // {uncovered - 32-bit error}
tlsClientNew(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(TEST_PATH "/client-pwd.key")),
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(TEST_PATH "/client-pwd.key")),
CryptoError, "unable to load key file '" TEST_PATH "/client-pwd.key': [151429224] bad password read");
}
TRY_END();
@ -428,9 +424,9 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNew(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(TEST_PATH "/client-bad-perm.key"))),
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(TEST_PATH "/client-bad-perm.key"))),
FileReadError,
"key file '" TEST_PATH "/client-bad-perm.key' has group or other permissions\n"
"HINT: file must have permissions u=rw (0600) or less if owned by the '" TEST_USER "' user\n"
@ -447,9 +443,9 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNew(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(TEST_PATH "/client-bad-perm.key"))),
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(TEST_PATH "/client-bad-perm.key"))),
FileReadError, "key file '" TEST_PATH "/client-bad-perm.key' must be owned by the '" TEST_USER "' user or root");
// -------------------------------------------------------------------------------------------------------------------------
@ -459,9 +455,9 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNew(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL, NULL,
STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(TEST_PATH "/client-bad-perm.key"))),
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(TEST_PATH "/client-bad-perm.key"))),
FileReadError,
"key file '" TEST_PATH "/client-bad-perm.key' has group or other permissions\n"
"HINT: file must have permissions u=rw (0600) or less if owned by the '" TEST_USER "' user\n"
@ -502,9 +498,9 @@ testRun(void)
TEST_ERROR_FMT(
ioClientOpen(
tlsClientNew(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true, NULL,
STRDEF("/bogus"), NULL, NULL)),
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
.caPath = STRDEF("/bogus"))),
CryptoError,
"unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate",
hrnServerPort(0));
@ -517,9 +513,9 @@ testRun(void)
TEST_RESULT_VOID(
ioClientOpen(
tlsClientNew(
tlsClientNewP(
sckClientNew(STRDEF("test.pgbackrest.org"), hrnServerPort(0), 5000, 5000),
STRDEF("test.pgbackrest.org"), 0, 0, true, STRDEF(HRN_SERVER_CA), NULL, NULL, NULL)),
STRDEF("test.pgbackrest.org"), 0, 0, true, .caFile = STRDEF(HRN_SERVER_CA))),
"open connection");
// -----------------------------------------------------------------------------------------------------------------
@ -530,9 +526,9 @@ testRun(void)
TEST_RESULT_VOID(
ioClientOpen(
tlsClientNew(
tlsClientNewP(
sckClientNew(STRDEF("host.test2.pgbackrest.org"), hrnServerPort(0), 5000, 5000),
STRDEF("host.test2.pgbackrest.org"), 0, 0, true, STRDEF(HRN_SERVER_CA), NULL, NULL, NULL)),
STRDEF("host.test2.pgbackrest.org"), 0, 0, true, .caFile = STRDEF(HRN_SERVER_CA))),
"open connection");
// -----------------------------------------------------------------------------------------------------------------
@ -543,9 +539,9 @@ testRun(void)
TEST_ERROR(
ioClientOpen(
tlsClientNew(
tlsClientNewP(
sckClientNew(STRDEF("test3.pgbackrest.org"), hrnServerPort(0), 5000, 5000),
STRDEF("test3.pgbackrest.org"), 0, 0, true, STRDEF(HRN_SERVER_CA), NULL, NULL, NULL)),
STRDEF("test3.pgbackrest.org"), 0, 0, true, .caFile = STRDEF(HRN_SERVER_CA))),
CryptoError,
"unable to find hostname 'test3.pgbackrest.org' in certificate common name or subject alternative names");
@ -557,9 +553,9 @@ testRun(void)
TEST_ERROR_FMT(
ioClientOpen(
tlsClientNew(
tlsClientNewP(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
STRDEF(HRN_SERVER_CERT), NULL, NULL, NULL)),
.caFile = STRDEF(HRN_SERVER_CERT))),
CryptoError,
"unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate",
hrnServerPort(0));
@ -572,10 +568,8 @@ testRun(void)
TEST_RESULT_VOID(
ioClientOpen(
tlsClientNew(
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, false, NULL, NULL,
NULL, NULL)),
"open connection");
tlsClientNewP(sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, false)),
"open connection");
// -----------------------------------------------------------------------------------------------------------------
hrnServerScriptEnd(tls);
@ -662,9 +656,10 @@ testRun(void)
TEST_ASSIGN(
clientSession,
ioClientOpen(
tlsClientNew(
tlsClientNewP(
sckClientNew(STRDEF("127.0.0.1"), hrnServerPort(0), 5000, 5000), STRDEF("127.0.0.1"), 5000, 5000,
true, NULL, NULL, STRDEF(TEST_PATH "/client-bad-ca.crt"), STRDEF(HRN_SERVER_CLIENT_KEY))),
true, .certFile = STRDEF(TEST_PATH "/client-bad-ca.crt"),
.keyFile = STRDEF(HRN_SERVER_CLIENT_KEY))),
"client open");
TEST_ERROR(
@ -680,9 +675,9 @@ testRun(void)
TEST_ASSIGN(
clientSession,
ioClientOpen(
tlsClientNew(
tlsClientNewP(
sckClientNew(STRDEF("127.0.0.1"), hrnServerPort(0), 5000, 5000), STRDEF("127.0.0.1"), 5000, 5000, true,
NULL, NULL, STRDEF(HRN_SERVER_CLIENT_CERT), STRDEF(HRN_SERVER_CLIENT_KEY))),
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(HRN_SERVER_CLIENT_KEY))),
"client open");
Buffer *buffer = bufNew(7);
@ -697,9 +692,9 @@ testRun(void)
TEST_ASSIGN(
clientSession,
ioClientOpen(
tlsClientNew(
sckClientNew(STRDEF("127.0.0.1"), hrnServerPort(0), 5000, 5000), STRDEF("127.0.0.1"), 5000, 5000, true,
NULL, NULL, NULL, NULL)),
tlsClientNewP(
sckClientNew(STRDEF("127.0.0.1"), hrnServerPort(0), 5000, 5000), STRDEF("127.0.0.1"), 5000, 5000,
true)),
"client open");
buffer = bufNew(8);
@ -738,9 +733,8 @@ testRun(void)
TEST_ASSIGN(
client,
tlsClientNew(
sckClientNew(hrnServerHost(), hrnServerPort(0), 5000, 5000), hrnServerHost(), 0, 0, TEST_IN_CONTAINER, NULL,
NULL, NULL, NULL),
tlsClientNewP(
sckClientNew(hrnServerHost(), hrnServerPort(0), 5000, 5000), hrnServerHost(), 0, 0, TEST_IN_CONTAINER),
"new client");
hrnServerScriptAccept(tls);

View File

@ -711,9 +711,8 @@ testRun(void)
TEST_TITLE("ping server");
// Connect to server without any verification
IoClient *tlsClient = tlsClientNew(
sckClientNew(hrnServerHost(), hrnServerPort(0), 5000, 5000), hrnServerHost(), 5000, 5000, false, NULL, NULL,
NULL, NULL);
IoClient *tlsClient = tlsClientNewP(
sckClientNew(hrnServerHost(), hrnServerPort(0), 5000, 5000), hrnServerHost(), 5000, 5000, false);
IoSession *tlsSession = ioClientOpen(tlsClient);
// Send ping