1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-11-06 08:49:29 +02:00

Improve SFTP storage error messages.

Use storageSftpEvalLibSsh2Error() in more locations to provide better error information. Also add storageSftpLibSsh2SessionLastError() for the same reason.
This commit is contained in:
Reid Thompson
2024-01-03 11:01:50 -05:00
committed by GitHub
parent 802ae79148
commit 7c17eec3db
6 changed files with 209 additions and 64 deletions

View File

@@ -68,6 +68,17 @@
<p>Skip files truncated during backup when bundling.</p> <p>Skip files truncated during backup when bundling.</p>
</release-item> </release-item>
<release-item>
<github-pull-request id="2249"/>
<release-item-contributor-list>
<release-item-contributor id="reid.thompson"/>
<release-item-reviewer id="david.steele"/>
</release-item-contributor-list>
<p>Improve <proper>SFTP</proper> storage error messages.</p>
</release-item>
</release-improvement-list> </release-improvement-list>
<release-development-list> <release-development-list>

View File

@@ -70,7 +70,11 @@ storageReadSftpOpen(THIS_VOID)
THROW_FMT(FileMissingError, STORAGE_ERROR_READ_MISSING, strZ(this->interface.name)); THROW_FMT(FileMissingError, STORAGE_ERROR_READ_MISSING, strZ(this->interface.name));
} }
else else
THROW_FMT(FileOpenError, STORAGE_ERROR_READ_OPEN, strZ(this->interface.name)); {
storageSftpEvalLibSsh2Error(
rc, libssh2_sftp_last_error(this->sftpSession), &FileOpenError,
strNewFmt(STORAGE_ERROR_READ_OPEN, strZ(this->interface.name)), NULL);
}
} }
} }
// Else success // Else success
@@ -152,7 +156,11 @@ storageReadSftp(THIS_VOID, Buffer *const buffer, const bool block)
else if (rc == LIBSSH2_ERROR_EAGAIN) else if (rc == LIBSSH2_ERROR_EAGAIN)
THROW_FMT(FileReadError, "timeout reading '%s'", strZ(this->interface.name)); THROW_FMT(FileReadError, "timeout reading '%s'", strZ(this->interface.name));
else else
THROW_FMT(FileReadError, "unable to read '%s'", strZ(this->interface.name)); {
storageSftpEvalLibSsh2Error(
(int)rc, libssh2_sftp_last_error(this->sftpSession), &FileReadError,
strNewFmt("unable to read '%s'", strZ(this->interface.name)), NULL);
}
} }
// Update amount of buffer used // Update amount of buffer used
@@ -201,7 +209,11 @@ storageReadSftpClose(THIS_VOID)
rc == LIBSSH2_ERROR_SFTP_PROTOCOL ? rc == LIBSSH2_ERROR_SFTP_PROTOCOL ?
strZ(strNewFmt(": sftp errno [%lu]", libssh2_sftp_last_error(this->sftpSession))) : ""); strZ(strNewFmt(": sftp errno [%lu]", libssh2_sftp_last_error(this->sftpSession))) : "");
else else
THROW_FMT(FileCloseError, "timeout closing file '%s'", strZ(this->interface.name)); {
storageSftpEvalLibSsh2Error(
rc, libssh2_sftp_last_error(this->sftpSession), &FileCloseError,
strNewFmt("timeout closing file '%s'", strZ(this->interface.name)), NULL);
}
} }
} }

View File

@@ -126,6 +126,28 @@ storageSftpKnownHostCheckpFailureMsg(const int rc)
FUNCTION_TEST_RETURN_CONST(STRINGZ, result); FUNCTION_TEST_RETURN_CONST(STRINGZ, result);
} }
/**********************************************************************************************************************************/
static String *
storageSftpLibSsh2SessionLastError(LIBSSH2_SESSION *const libSsh2Session)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM_P(VOID, libSsh2Session);
FUNCTION_TEST_END();
String *result;
char *libSsh2ErrMsg;
int libSsh2ErrMsgLen;
const int rc = libssh2_session_last_error(libSsh2Session, &libSsh2ErrMsg, &libSsh2ErrMsgLen, 0);
if (libSsh2ErrMsgLen != 0)
result = strNewZN(libSsh2ErrMsg, (size_t)libSsh2ErrMsgLen);
else
result = strNewFmt("libssh2 no session error message provided [%d]", rc);
FUNCTION_TEST_RETURN(STRING, result);
}
/*********************************************************************************************************************************** /***********************************************************************************************************************************
Rewrite the user's known_hosts file with a new entry Rewrite the user's known_hosts file with a new entry
***********************************************************************************************************************************/ ***********************************************************************************************************************************/
@@ -143,8 +165,6 @@ storageSftpUpdateKnownHostsFile(
MEM_CONTEXT_TEMP_BEGIN() MEM_CONTEXT_TEMP_BEGIN()
{ {
char *libSsh2ErrMsg;
int libSsh2ErrMsgLen;
int rc; int rc;
// Init a known host collection for the user's known_hosts file // Init a known host collection for the user's known_hosts file
@@ -156,10 +176,10 @@ storageSftpUpdateKnownHostsFile(
if (userKnownHostsList == NULL) if (userKnownHostsList == NULL)
{ {
// Get the libssh2 error message and emit warning // Get the libssh2 error message and emit warning
rc = libssh2_session_last_error(this->session, &libSsh2ErrMsg, &libSsh2ErrMsgLen, 0); const int rc = libssh2_session_last_errno(this->session);
LOG_WARN_FMT( LOG_WARN_FMT(
"libssh2_knownhost_init failed for '%s' for update: libssh2 errno [%d] %s", userKnownHostsFile, rc, libSsh2ErrMsg); "libssh2_knownhost_init failed for '%s' for update: libssh2 errno [%d] %s", userKnownHostsFile, rc,
strZ(storageSftpLibSsh2SessionLastError(this->session)));
} }
else else
{ {
@@ -214,11 +234,10 @@ storageSftpUpdateKnownHostsFile(
else else
{ {
// On readfile failure warn that we're unable to update the user's known_hosts file // On readfile failure warn that we're unable to update the user's known_hosts file
rc = libssh2_session_last_error(this->session, &libSsh2ErrMsg, &libSsh2ErrMsgLen, 0);
LOG_WARN_FMT( LOG_WARN_FMT(
"libssh2 unable to read '%s' for update: libssh2 errno [%d] %s\n" "libssh2 unable to read '%s' for update: libssh2 errno [%d] %s\n"
"HINT: does '%s' exist with proper permissions?", userKnownHostsFile, rc, libSsh2ErrMsg, userKnownHostsFile); "HINT: does '%s' exist with proper permissions?", userKnownHostsFile, rc,
strZ(storageSftpLibSsh2SessionLastError(this->session)), userKnownHostsFile);
} }
} }
@@ -342,7 +361,8 @@ storageSftpEvalLibSsh2Error(
ASSERT(errorType != NULL); ASSERT(errorType != NULL);
THROWP_FMT( THROWP_FMT(
errorType, "%slibssh2 error [%d]%s%s", message != NULL ? zNewFmt("%s: ", strZ(message)) : "", ssh2Errno, errorType, "%s%s%s%s", message != NULL ? zNewFmt("%s%s", strZ(message), ssh2Errno == 0 ? "" : ": ") : "",
ssh2Errno == 0 ? "" : zNewFmt("libssh2 error [%d]", ssh2Errno),
ssh2Errno == LIBSSH2_ERROR_SFTP_PROTOCOL ? zNewFmt(": sftp error [%" PRIu64 "]", sftpErrno) : "", ssh2Errno == LIBSSH2_ERROR_SFTP_PROTOCOL ? zNewFmt(": sftp error [%" PRIu64 "]", sftpErrno) : "",
hint != NULL ? zNewFmt("\n%s", strZ(hint)) : ""); hint != NULL ? zNewFmt("\n%s", strZ(hint)) : "");
@@ -433,7 +453,10 @@ storageSftpInfo(THIS_VOID, const String *const file, const StorageInfoLevel leve
// Throw libssh2 on errors other than no such file // Throw libssh2 on errors other than no such file
if (!storageSftpLibSsh2FxNoSuchFile(this, rc)) if (!storageSftpLibSsh2FxNoSuchFile(this, rc))
THROW_FMT(FileOpenError, STORAGE_ERROR_INFO, strZ(file)); {
storageSftpEvalLibSsh2Error(
rc, libssh2_sftp_last_error(this->sftpSession), &FileOpenError, strNewFmt(STORAGE_ERROR_INFO, strZ(file)), NULL);
}
} }
// Else the file exists // Else the file exists
else else
@@ -491,7 +514,11 @@ storageSftpInfo(THIS_VOID, const String *const file, const StorageInfoLevel leve
THROW_FMT(FileReadError, "timeout getting destination for link '%s'", strZ(file)); THROW_FMT(FileReadError, "timeout getting destination for link '%s'", strZ(file));
if (linkDestinationSize < 0) if (linkDestinationSize < 0)
THROW_FMT(FileReadError, "unable to get destination for link '%s'", strZ(file)); {
storageSftpEvalLibSsh2Error(
(int)linkDestinationSize, libssh2_sftp_last_error(this->sftpSession), &FileReadError,
strNewFmt("unable to get destination for link '%s'", strZ(file)), NULL);
}
result.linkDestination = strNewZN(linkDestination, (size_t)linkDestinationSize); result.linkDestination = strNewZN(linkDestination, (size_t)linkDestinationSize);
} }
@@ -706,7 +733,11 @@ storageSftpList(THIS_VOID, const String *const path, const StorageInfoLevel leve
if (rc != 0) if (rc != 0)
{ {
if (rc != LIBSSH2_ERROR_EAGAIN) if (rc != LIBSSH2_ERROR_EAGAIN)
THROW_FMT(PathCloseError, "unable to close path '%s' after listing", strZ(path)); {
storageSftpEvalLibSsh2Error(
rc, libssh2_sftp_last_error(this->sftpSession), &PathCloseError,
strNewFmt("unable to close path '%s' after listing", strZ(path)), NULL);
}
else else
THROW_FMT(PathCloseError, "timeout closing path '%s' after listing", strZ(path)); THROW_FMT(PathCloseError, "timeout closing path '%s' after listing", strZ(path));
} }
@@ -760,7 +791,11 @@ storageSftpRemove(THIS_VOID, const String *const file, const StorageInterfaceRem
else else
{ {
if (param.errorOnMissing) if (param.errorOnMissing)
THROW_FMT(FileRemoveError, "unable to remove '%s'", strZ(file)); {
storageSftpEvalLibSsh2Error(
rc, libssh2_sftp_last_error(this->sftpSession), &FileRemoveError,
strNewFmt("unable to remove '%s'", strZ(file)), NULL);
}
} }
} }
@@ -879,11 +914,15 @@ storageSftpPathCreate(
while (storageSftpWaitFd(this, rc)); while (storageSftpWaitFd(this, rc));
if (rc == LIBSSH2_ERROR_EAGAIN) if (rc == LIBSSH2_ERROR_EAGAIN)
THROW_FMT(PathCreateError, "timeout stating path '%s'", strZ(path)); THROW_FMT(PathCreateError, "timeout stat'ing path '%s'", strZ(path));
// If rc = 0 then already exists // If rc = 0 then already exists
if (rc == 0 && errorOnExists) if (rc == 0 && errorOnExists)
THROW_FMT(PathCreateError, "unable to create path '%s': path already exists", strZ(path)); {
storageSftpEvalLibSsh2Error(
rc, libssh2_sftp_last_error(this->sftpSession), &PathCreateError,
strNewFmt("unable to create path '%s': path already exists", strZ(path)), NULL);
}
} }
// If the parent path does not exist then create it if allowed // If the parent path does not exist then create it if allowed
else if (sftpErrno == LIBSSH2_FX_NO_SUCH_FILE && !noParentCreate) else if (sftpErrno == LIBSSH2_FX_NO_SUCH_FILE && !noParentCreate)
@@ -896,10 +935,17 @@ storageSftpPathCreate(
strFree(pathParent); strFree(pathParent);
} }
else if (sftpErrno != LIBSSH2_FX_FILE_ALREADY_EXISTS || errorOnExists) else if (sftpErrno != LIBSSH2_FX_FILE_ALREADY_EXISTS || errorOnExists)
THROW_FMT(PathCreateError, "sftp error unable to create path '%s'", strZ(path)); {
storageSftpEvalLibSsh2Error(
rc, sftpErrno, &PathCreateError, strNewFmt("sftp error unable to create path '%s'", strZ(path)), NULL);
}
} }
else else
THROW_FMT(PathCreateError, "ssh2 error [%d] unable to create path '%s'", rc, strZ(path)); {
storageSftpEvalLibSsh2Error(
rc, libssh2_sftp_last_error(this->sftpSession), &PathCreateError,
strNewFmt("ssh2 error [%d] unable to create path '%s'", rc, strZ(path)), NULL);
}
} }
FUNCTION_LOG_RETURN_VOID(); FUNCTION_LOG_RETURN_VOID();
@@ -1007,7 +1053,9 @@ storageSftpPathRemove(THIS_VOID, const String *const path, const bool recurse, c
// Path does not exist // Path does not exist
result = false; result = false;
THROW_FMT(PathRemoveError, STORAGE_ERROR_PATH_REMOVE, strZ(path)); storageSftpEvalLibSsh2Error(
rc, libssh2_sftp_last_error(this->sftpSession), &PathRemoveError,
strNewFmt(STORAGE_ERROR_PATH_REMOVE, strZ(path)), NULL);
} }
} }
} }
@@ -1098,7 +1146,10 @@ storageSftpNew(
THROW_FMT(ServiceError, "timeout during libssh2 handshake [%d]", rc); THROW_FMT(ServiceError, "timeout during libssh2 handshake [%d]", rc);
if (rc != 0) if (rc != 0)
THROW_FMT(ServiceError, "libssh2 handshake failed [%d]", rc); {
THROW_FMT(
ServiceError, "libssh2 handshake failed [%d]: %s", rc, strZ(storageSftpLibSsh2SessionLastError(this->session)));
}
int hashType = LIBSSH2_HOSTKEY_HASH_SHA1; int hashType = LIBSSH2_HOSTKEY_HASH_SHA1;
size_t hashSize = 0; size_t hashSize = 0;
@@ -1158,7 +1209,14 @@ storageSftpNew(
LIBSSH2_KNOWNHOSTS *const knownHostsList = libssh2_knownhost_init(this->session); LIBSSH2_KNOWNHOSTS *const knownHostsList = libssh2_knownhost_init(this->session);
if (knownHostsList == NULL) if (knownHostsList == NULL)
THROW_FMT(ServiceError, "failure during libssh2_knownhost_init"); {
const int rc = libssh2_session_last_errno(this->session);
THROW_FMT(
ServiceError,
"failure during libssh2_knownhost_init: libssh2 errno [%d] %s", rc,
strZ(storageSftpLibSsh2SessionLastError(this->session)));
}
// Get the list of known host files to search // Get the list of known host files to search
const StringList *const knownHostsPathList = storageSftpKnownHostsFilesList(param.knownHosts); const StringList *const knownHostsPathList = storageSftpKnownHostsFilesList(param.knownHosts);
@@ -1177,14 +1235,9 @@ storageSftpNew(
LOG_DETAIL_FMT("libssh2 '%s' file is empty", currentKnownHostFile); LOG_DETAIL_FMT("libssh2 '%s' file is empty", currentKnownHostFile);
else else
{ {
char *libSsh2ErrMsg;
int libSsh2ErrMsgLen;
// Get the libssh2 error message
rc = libssh2_session_last_error(this->session, &libSsh2ErrMsg, &libSsh2ErrMsgLen, 0);
LOG_DETAIL_FMT( LOG_DETAIL_FMT(
"libssh2 read '%s' failed: libssh2 errno [%d] %s", currentKnownHostFile, rc, libSsh2ErrMsg); "libssh2 read '%s' failed: libssh2 errno [%d] %s", currentKnownHostFile, rc,
strZ(storageSftpLibSsh2SessionLastError(this->session)));
} }
} }
else else
@@ -1305,7 +1358,11 @@ storageSftpNew(
if (libssh2_session_last_errno(this->session) == LIBSSH2_ERROR_EAGAIN) if (libssh2_session_last_errno(this->session) == LIBSSH2_ERROR_EAGAIN)
THROW_FMT(ServiceError, "timeout during init of libssh2_sftp session"); THROW_FMT(ServiceError, "timeout during init of libssh2_sftp session");
else else
THROW_FMT(ServiceError, "unable to init libssh2_sftp session"); {
storageSftpEvalLibSsh2Error(
rc, libssh2_sftp_last_error(this->sftpSession), &ServiceError,
strNewFmt("unable to init libssh2_sftp session"), NULL);
}
} }
// Ensure libssh2/libssh2_sftp resources freed // Ensure libssh2/libssh2_sftp resources freed

View File

@@ -98,7 +98,11 @@ storageWriteSftpOpen(THIS_VOID)
} }
} }
else else
THROW_FMT(FileOpenError, STORAGE_ERROR_WRITE_OPEN, strZ(this->interface.name)); {
storageSftpEvalLibSsh2Error(
rc, libssh2_sftp_last_error(this->sftpSession), &FileOpenError,
strNewFmt(STORAGE_ERROR_WRITE_OPEN, strZ(this->interface.name)), NULL);
}
} }
FUNCTION_LOG_RETURN_VOID(); FUNCTION_LOG_RETURN_VOID();
@@ -150,7 +154,11 @@ storageWriteSftp(THIS_VOID, const Buffer *const buffer)
THROW_FMT(FileWriteError, "timeout writing '%s'", strZ(this->nameTmp)); THROW_FMT(FileWriteError, "timeout writing '%s'", strZ(this->nameTmp));
if (rc < 0) if (rc < 0)
THROW_FMT(FileWriteError, "unable to write '%s'", strZ(this->nameTmp)); {
storageSftpEvalLibSsh2Error(
(int)rc, libssh2_sftp_last_error(this->sftpSession), &FileWriteError,
strNewFmt("unable to write '%s'", strZ(this->nameTmp)), NULL);
}
FUNCTION_LOG_RETURN_VOID(); FUNCTION_LOG_RETURN_VOID();
} }
@@ -261,7 +269,11 @@ storageWriteSftpClose(THIS_VOID)
if (rc == LIBSSH2_ERROR_EAGAIN) if (rc == LIBSSH2_ERROR_EAGAIN)
THROW_FMT(FileSyncError, "timeout syncing file '%s'", strZ(this->nameTmp)); THROW_FMT(FileSyncError, "timeout syncing file '%s'", strZ(this->nameTmp));
else else
THROW_FMT(FileSyncError, STORAGE_ERROR_WRITE_SYNC, strZ(this->nameTmp)); {
storageSftpEvalLibSsh2Error(
rc, libssh2_sftp_last_error(this->sftpSession), &FileSyncError,
strNewFmt(STORAGE_ERROR_WRITE_SYNC, strZ(this->nameTmp)), NULL);
}
} }
} }

View File

@@ -377,13 +377,20 @@ int
libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf) libssh2_session_last_error(LIBSSH2_SESSION *session, char **errmsg, int *errmsg_len, int want_buf)
{ {
// Avoid compiler complaining of unused params // Avoid compiler complaining of unused params
(void)errmsg_len;
(void)want_buf; (void)want_buf;
HrnLibSsh2 *hrnLibSsh2 = hrnLibSsh2ScriptRun(HRNLIBSSH2_SESSION_LAST_ERROR, NULL, (HrnLibSsh2 *)session); HrnLibSsh2 *hrnLibSsh2 = hrnLibSsh2ScriptRun(HRNLIBSSH2_SESSION_LAST_ERROR, NULL, (HrnLibSsh2 *)session);
if (hrnLibSsh2->errMsg != NULL) if (hrnLibSsh2->errMsg != NULL)
{
*errmsg = hrnLibSsh2->errMsg; *errmsg = hrnLibSsh2->errMsg;
*errmsg_len = (int)(strlen(hrnLibSsh2->errMsg) + 1);
}
else
{
*errmsg = NULL;
*errmsg_len = 0;
}
return hrnLibSsh2->resultInt; return hrnLibSsh2->resultInt;
} }

View File

@@ -120,7 +120,9 @@ testRun(void)
{.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"},
{.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_EAGAIN}, {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_EAGAIN},
{.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_WRITING}, {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_WRITING},
{.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = -1}, {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_BAD_SOCKET},
{.function = HRNLIBSSH2_SESSION_LAST_ERROR, .resultInt = LIBSSH2_ERROR_BAD_SOCKET,
.errMsg = (char *)"Bad socket provided"},
{.function = NULL} {.function = NULL}
}); });
@@ -128,7 +130,7 @@ testRun(void)
storageSftpNewP( storageSftpNewP(
TEST_PATH_STR, STRDEF("localhost"), 22, TEST_USER_STR, 1000, KEYPRIV, hashTypeSha1, .keyPub = KEYPUB, TEST_PATH_STR, STRDEF("localhost"), 22, TEST_USER_STR, 1000, KEYPRIV, hashTypeSha1, .keyPub = KEYPUB,
.hostKeyCheckType = SFTP_STRICT_HOSTKEY_CHECKING_STRICT), .hostKeyCheckType = SFTP_STRICT_HOSTKEY_CHECKING_STRICT),
ServiceError, "libssh2 handshake failed [-1]"); ServiceError, "libssh2 handshake failed [-45]: Bad socket provided");
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("handshake failure - timeout during libssh2 handshake"); TEST_TITLE("handshake failure - timeout during libssh2 handshake");
@@ -291,6 +293,9 @@ testRun(void)
{.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"}, {.function = HRNLIBSSH2_SESSION_INIT_EX, .param = "[null,null,null,null]"},
{.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE}, {.function = HRNLIBSSH2_SESSION_HANDSHAKE, .param = HANDSHAKE_PARAM, .resultInt = LIBSSH2_ERROR_NONE},
{.function = HRNLIBSSH2_KNOWNHOST_INIT, .resultNull = true}, {.function = HRNLIBSSH2_KNOWNHOST_INIT, .resultNull = true},
{.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_ALLOC},
{.function = HRNLIBSSH2_SESSION_LAST_ERROR, .resultInt = LIBSSH2_ERROR_ALLOC,
.errMsg = (char *)"Unable to allocate memory for known-hosts collection"},
{.function = NULL} {.function = NULL}
}); });
@@ -321,7 +326,7 @@ testRun(void)
.hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx),
.knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))),
ServiceError, ServiceError,
"failure during libssh2_knownhost_init"); "failure during libssh2_knownhost_init: libssh2 errno [-6] Unable to allocate memory for known-hosts collection");
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("libssh2_session_hostkey fail - return NULL - hostKeyCheckType = yes"); TEST_TITLE("libssh2_session_hostkey fail - return NULL - hostKeyCheckType = yes");
@@ -653,6 +658,7 @@ testRun(void)
// storageSftpWaitFd returns false // storageSftpWaitFd returns false
{.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND},
{.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
{.function = NULL} {.function = NULL}
}); });
@@ -731,6 +737,7 @@ testRun(void)
{.function = HRNLIBSSH2_SFTP_INIT, .resultNull = true}, {.function = HRNLIBSSH2_SFTP_INIT, .resultNull = true},
{.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND},
{.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
{.function = NULL} {.function = NULL}
}); });
@@ -840,6 +847,7 @@ testRun(void)
{.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]",
.resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND},
{.function = HRNLIBSSH2_KNOWNHOST_INIT, .resultNull = true}, {.function = HRNLIBSSH2_KNOWNHOST_INIT, .resultNull = true},
{.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_ALLOC},
{.function = HRNLIBSSH2_SESSION_LAST_ERROR, .resultInt = LIBSSH2_ERROR_ALLOC, {.function = HRNLIBSSH2_SESSION_LAST_ERROR, .resultInt = LIBSSH2_ERROR_ALLOC,
.errMsg = (char *)"Unable to allocate memory for known-hosts collection"}, .errMsg = (char *)"Unable to allocate memory for known-hosts collection"},
{.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX, {.function = HRNLIBSSH2_USERAUTH_PUBLICKEY_FROMFILE_EX,
@@ -1080,7 +1088,7 @@ testRun(void)
{.function = HRNLIBSSH2_SESSION_LAST_ERROR, .errMsg = (char *)"Failed to open file", .resultInt = LIBSSH2_ERROR_FILE}, {.function = HRNLIBSSH2_SESSION_LAST_ERROR, .errMsg = (char *)"Failed to open file", .resultInt = LIBSSH2_ERROR_FILE},
{.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS2_FILE_CSTR "\",1]", {.function = HRNLIBSSH2_KNOWNHOST_READFILE, .param = "[\"" ETC_KNOWNHOSTS2_FILE_CSTR "\",1]",
.resultInt = LIBSSH2_ERROR_FILE}, .resultInt = LIBSSH2_ERROR_FILE},
{.function = HRNLIBSSH2_SESSION_LAST_ERROR, .errMsg = (char *)"Failed to open file", .resultInt = LIBSSH2_ERROR_FILE}, {.function = HRNLIBSSH2_SESSION_LAST_ERROR, .resultInt = LIBSSH2_ERROR_FILE},
{.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY}, {.function = HRNLIBSSH2_SESSION_HOSTKEY, .len = 20, .type = LIBSSH2_HOSTKEY_TYPE_RSA, .resultZ = HOSTKEY},
{.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]", {.function = HRNLIBSSH2_KNOWNHOST_CHECKP, .param = "[\"localhost\",22,\"" HOSTKEY "\",20,65537]",
.resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND}, .resultInt = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND},
@@ -1114,6 +1122,7 @@ testRun(void)
storageTest = NULL; storageTest = NULL;
harnessLogLevelSet(logLevelDetail);
TEST_ASSIGN( TEST_ASSIGN(
storageTest, storageTest,
storageSftpNewP( storageSftpNewP(
@@ -1128,10 +1137,17 @@ testRun(void)
.knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))), .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx))),
"new storage (defaults)"); "new storage (defaults)");
TEST_RESULT_LOG( TEST_RESULT_LOG(
"P00 DETAIL: libssh2 '/home/" TEST_USER "/.ssh/known_hosts' file is empty\n"
"P00 DETAIL: libssh2 read '/home/" TEST_USER "/.ssh/known_hosts2' failed: libssh2 errno [-16] Failed to open file\n"
"P00 DETAIL: libssh2 read '/etc/ssh/ssh_known_hosts' failed: libssh2 errno [-16] Failed to open file\n"
"P00 DETAIL: libssh2 read '/etc/ssh/ssh_known_hosts2' failed: libssh2 errno [-16] libssh2 no session error message "
"provided [-16]\n"
"P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to " "P00 WARN: host 'localhost' not found in known hosts files, attempting to add host to "
"'/home/" TEST_USER "/.ssh/known_hosts'\n" "'/home/" TEST_USER "/.ssh/known_hosts'\n"
"P00 WARN: pgBackRest added new host 'localhost' to '/home/" TEST_USER "/.ssh/known_hosts'"); "P00 WARN: pgBackRest added new host 'localhost' to '/home/" TEST_USER "/.ssh/known_hosts'");
harnessLogLevelReset();
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
@@ -1250,7 +1266,7 @@ testRun(void)
#ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384 #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("sftp session init success - hostKeyCheckType = accept_new - add host to user's known_hosts ECDSA_384"); TEST_TITLE("sftp session init success - hostKeyCheckType = accept-new - add host to user's known_hosts ECDSA_384");
hrnLibSsh2ScriptSet((HrnLibSsh2 []) hrnLibSsh2ScriptSet((HrnLibSsh2 [])
{ {
@@ -2064,9 +2080,11 @@ testRun(void)
{.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",0]", {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",0]",
.resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED},
{.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",0]", {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",0]",
.resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED},
// File and path // File and path
{.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/exists\",0]", {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/exists\",0]",
.attrPerms = LIBSSH2_SFTP_S_IFREG, .resultInt = LIBSSH2_ERROR_NONE}, .attrPerms = LIBSSH2_SFTP_S_IFREG, .resultInt = LIBSSH2_ERROR_NONE},
@@ -2135,8 +2153,12 @@ testRun(void)
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("permission denied"); TEST_TITLE("permission denied");
TEST_ERROR_FMT(storageExistsP(storageTest, fileNoPerm), FileOpenError, STORAGE_ERROR_INFO, strZ(fileNoPerm)); TEST_ERROR_FMT(
TEST_ERROR_FMT(storagePathExistsP(storageTest, fileNoPerm), FileOpenError, STORAGE_ERROR_INFO, strZ(fileNoPerm)); storageExistsP(storageTest, fileNoPerm),
FileOpenError, STORAGE_ERROR_INFO ": libssh2 error [-31]: sftp error [3]", strZ(fileNoPerm));
TEST_ERROR_FMT(
storagePathExistsP(storageTest, fileNoPerm),
FileOpenError, STORAGE_ERROR_INFO ": libssh2 error [-31]: sftp error [3]", strZ(fileNoPerm));
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("file and path"); TEST_TITLE("file and path");
@@ -2187,6 +2209,7 @@ testRun(void)
{.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",1]", {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",1]",
.resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED},
HRNLIBSSH2_MACRO_SHUTDOWN() HRNLIBSSH2_MACRO_SHUTDOWN()
}); });
@@ -2202,7 +2225,9 @@ testRun(void)
.hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx),
.knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true);
TEST_ERROR_FMT(storageInfoP(storageTest, fileNoPerm), FileOpenError, STORAGE_ERROR_INFO, strZ(fileNoPerm)); TEST_ERROR_FMT(
storageInfoP(storageTest, fileNoPerm),
FileOpenError, STORAGE_ERROR_INFO ": libssh2 error [-31]: sftp error [3]", strZ(fileNoPerm));
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -2211,6 +2236,7 @@ testRun(void)
{ {
HRNLIBSSH2_MACRO_STARTUP(), HRNLIBSSH2_MACRO_STARTUP(),
{.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",1]", .resultInt = LIBSSH2_ERROR_INVAL}, {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/noperm/noperm\",1]", .resultInt = LIBSSH2_ERROR_INVAL},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
HRNLIBSSH2_MACRO_SHUTDOWN() HRNLIBSSH2_MACRO_SHUTDOWN()
}); });
@@ -2226,7 +2252,8 @@ testRun(void)
.hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx), .hostKeyCheckType = cfgOptionIdxStrId(cfgOptRepoSftpHostKeyCheckType, repoIdx),
.knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true);
TEST_ERROR_FMT(storageInfoP(storageTest, fileNoPerm), FileOpenError, STORAGE_ERROR_INFO, strZ(fileNoPerm)); TEST_ERROR_FMT(
storageInfoP(storageTest, fileNoPerm), FileOpenError, STORAGE_ERROR_INFO ": libssh2 error [-34]", strZ(fileNoPerm));
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -2376,6 +2403,7 @@ testRun(void)
{.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING},
{.function = HRNLIBSSH2_SFTP_SYMLINK_EX, .param = "[\"" TEST_PATH "/testlink\",\"\",1]", {.function = HRNLIBSSH2_SFTP_SYMLINK_EX, .param = "[\"" TEST_PATH "/testlink\",\"\",1]",
.resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_LINK_LOOP},
// Info - pipe // Info - pipe
{.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/testpipe\",1]", .resultInt = LIBSSH2_ERROR_NONE, {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/testpipe\",1]", .resultInt = LIBSSH2_ERROR_NONE,
.attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | .attrPerms = LIBSSH2_SFTP_S_IFIFO | LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP |
@@ -2535,7 +2563,7 @@ testRun(void)
// libssh2_sftp_symlink_ex fail link destination followLink false // libssh2_sftp_symlink_ex fail link destination followLink false
TEST_ERROR_FMT( TEST_ERROR_FMT(
storageInfoP(storageTest, linkName, .followLink = false), FileReadError, storageInfoP(storageTest, linkName, .followLink = false), FileReadError,
"unable to get destination for link '" TEST_PATH "/testlink'"); "unable to get destination for link '" TEST_PATH "/testlink': libssh2 error [-31]: sftp error [21]");
// -------------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("info - pipe"); TEST_TITLE("info - pipe");
@@ -3809,6 +3837,7 @@ testRun(void)
.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID, .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID,
.mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, .mtime = 1555160000, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID},
{.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_SOCKET_RECV}, {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_SOCKET_RECV},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
HRNLIBSSH2_MACRO_SHUTDOWN() HRNLIBSSH2_MACRO_SHUTDOWN()
}); });
@@ -3848,7 +3877,7 @@ testRun(void)
TEST_ERROR_FMT( TEST_ERROR_FMT(
storageListP(storageTest, NULL, .errorOnMissing = true), PathCloseError, storageListP(storageTest, NULL, .errorOnMissing = true), PathCloseError,
"unable to close path '" TEST_PATH "' after listing"); "unable to close path '" TEST_PATH "' after listing: libssh2 error [-43]");
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
#else #else
@@ -4000,6 +4029,8 @@ testRun(void)
// create /sub1 again fails mkdir_ex ssh error // create /sub1 again fails mkdir_ex ssh error
{.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]", {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]",
.resultInt = LIBSSH2_ERROR_SOCKET_SEND}, .resultInt = LIBSSH2_ERROR_SOCKET_SEND},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
// create /sub1 again no error on file already exists, file already exists // create /sub1 again no error on file already exists, file already exists
{.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]", {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]",
.resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL},
@@ -4031,6 +4062,7 @@ testRun(void)
.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID | .flags = LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME | LIBSSH2_SFTP_ATTR_UIDGID |
LIBSSH2_SFTP_ATTR_SIZE, LIBSSH2_SFTP_ATTR_SIZE,
.mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID}, .mtime = 1656434296, .uid = TEST_USER_ID, .gid = TEST_GROUP_ID},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
// sub2 custom mode // sub2 custom mode
{.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub2\",511]", .resultInt = LIBSSH2_ERROR_NONE}, {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub2\",511]", .resultInt = LIBSSH2_ERROR_NONE},
{.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/sub2\",1]", .resultInt = LIBSSH2_ERROR_NONE, {.function = HRNLIBSSH2_SFTP_STAT_EX, .param = "[\"" TEST_PATH "/sub2\",1]", .resultInt = LIBSSH2_ERROR_NONE,
@@ -4088,11 +4120,11 @@ testRun(void)
TEST_RESULT_INT(storageInfoP(storageTest, STRDEF("sub1")).mode, 0750, "check sub1 dir mode"); TEST_RESULT_INT(storageInfoP(storageTest, STRDEF("sub1")).mode, 0750, "check sub1 dir mode");
TEST_ERROR( TEST_ERROR(
storagePathCreateP(storageTest, STRDEF("sub1")), PathCreateError, storagePathCreateP(storageTest, STRDEF("sub1")), PathCreateError,
"ssh2 error [-7] unable to create path '" TEST_PATH "/sub1'"); "ssh2 error [-7] unable to create path '" TEST_PATH "/sub1': libssh2 error [-7]");
TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("sub1")), "create sub1 again no .errorOnExists fail EAGAIN"); TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("sub1")), "create sub1 again no .errorOnExists fail EAGAIN");
TEST_RESULT_VOID( TEST_RESULT_VOID(
storagePathCreateP(storageTest, STRDEF("sub1")), "create sub1 again no .errorOnExists fail other than EAGAIN"); storagePathCreateP(storageTest, STRDEF("sub1")), "create sub1 again no .errorOnExists fail other than EAGAIN");
TEST_ERROR(storagePathCreateP(storageTest, STRDEF("sub1")), PathCreateError, "timeout stating path '" TEST_PATH "/sub1'"); TEST_ERROR(storagePathCreateP(storageTest, STRDEF("sub1")), PathCreateError, "timeout stat'ing path '" TEST_PATH "/sub1'");
TEST_ERROR( TEST_ERROR(
storagePathCreateP(storageTest, STRDEF("sub1"), .errorOnExists = true), PathCreateError, storagePathCreateP(storageTest, STRDEF("sub1"), .errorOnExists = true), PathCreateError,
"unable to create path '" TEST_PATH "/sub1': path already exists"); "unable to create path '" TEST_PATH "/sub1': path already exists");
@@ -4104,7 +4136,7 @@ testRun(void)
TEST_ERROR( TEST_ERROR(
storagePathCreateP(storageTest, STRDEF("sub3/sub4"), .noParentCreate = true), PathCreateError, storagePathCreateP(storageTest, STRDEF("sub3/sub4"), .noParentCreate = true), PathCreateError,
"sftp error unable to create path '" TEST_PATH "/sub3/sub4'"); "sftp error unable to create path '" TEST_PATH "/sub3/sub4': libssh2 error [-31]: sftp error [2]");
TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("sub3/sub4")), "create sub3/sub4"); TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("sub3/sub4")), "create sub3/sub4");
// LIBSSH2_ERROR_EAGAIN timeout fail // LIBSSH2_ERROR_EAGAIN timeout fail
@@ -4160,11 +4192,11 @@ testRun(void)
TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("subfail")), "timeout success"); TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("subfail")), "timeout success");
TEST_ERROR( TEST_ERROR(
storagePathCreateP(storageTest, STRDEF("subfail"), .noParentCreate = true), PathCreateError, storagePathCreateP(storageTest, STRDEF("subfail"), .noParentCreate = true), PathCreateError,
"sftp error unable to create path '" TEST_PATH "/subfail'"); "sftp error unable to create path '" TEST_PATH "/subfail': libssh2 error [-31]: sftp error [3]");
TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("subfail")), "do not throw error on already exists"); TEST_RESULT_VOID(storagePathCreateP(storageTest, STRDEF("subfail")), "do not throw error on already exists");
TEST_ERROR( TEST_ERROR(
storagePathCreateP(storageTest, STRDEF("subfail"), .errorOnExists = true), PathCreateError, storagePathCreateP(storageTest, STRDEF("subfail"), .errorOnExists = true), PathCreateError,
"sftp error unable to create path '" TEST_PATH "/subfail'"); "sftp error unable to create path '" TEST_PATH "/subfail': libssh2 error [-31]: sftp error [11]");
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
#else #else
@@ -4521,6 +4553,7 @@ testRun(void)
.resultInt = LIBSSH2_ERROR_NONE}, .resultInt = LIBSSH2_ERROR_NONE},
{.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE}, {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_NONE},
{.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1\"]", .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, {.function = HRNLIBSSH2_SFTP_RMDIR_EX, .param = "[\"" TEST_PATH "/remove1\"]", .resultInt = LIBSSH2_ERROR_SOCKET_SEND},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
HRNLIBSSH2_MACRO_SHUTDOWN() HRNLIBSSH2_MACRO_SHUTDOWN()
}); });
@@ -4538,8 +4571,8 @@ testRun(void)
.knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true), .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true),
"new storage /"); "new storage /");
TEST_ERROR_FMT( TEST_ERROR_FMT(
storagePathRemoveP(storageTest, pathRemove1, .recurse = true), PathRemoveError, "unable to remove path '%s'", storagePathRemoveP(storageTest, pathRemove1, .recurse = true), PathRemoveError,
strZ(pathRemove1)); "unable to remove path '%s': libssh2 error [-7]", strZ(pathRemove1));
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
#else #else
@@ -4572,6 +4605,7 @@ testRun(void)
{.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING},
{.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN}, {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_EAGAIN},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_OK}, {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_OK},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
// Error not sftp, not EAGAIN // Error not sftp, not EAGAIN
{.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]", .resultNull = true}, {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]", .resultNull = true},
{.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_METHOD_NOT_SUPPORTED}, {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_METHOD_NOT_SUPPORTED},
@@ -4605,7 +4639,7 @@ testRun(void)
TEST_ERROR_FMT(ioReadOpen(storageReadIo(file)), FileMissingError, STORAGE_ERROR_READ_MISSING, strZ(fileName)); TEST_ERROR_FMT(ioReadOpen(storageReadIo(file)), FileMissingError, STORAGE_ERROR_READ_MISSING, strZ(fileName));
// Missing EAGAIN timeout // Missing EAGAIN timeout
TEST_ERROR_FMT(ioReadOpen(storageReadIo(file)), FileOpenError, STORAGE_ERROR_READ_OPEN, strZ(fileName)); TEST_ERROR_FMT(ioReadOpen(storageReadIo(file)), FileOpenError, STORAGE_ERROR_READ_OPEN ": libssh2 error [-37]", strZ(fileName));
// Missing not sftp, not EAGAIN // Missing not sftp, not EAGAIN
TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), false, "not sftp, not EAGAIN"); TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), false, "not sftp, not EAGAIN");
@@ -4731,6 +4765,7 @@ testRun(void)
{.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]"}, {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]"},
{.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_EAGAIN}, {.function = HRNLIBSSH2_SFTP_CLOSE_HANDLE, .resultInt = LIBSSH2_ERROR_EAGAIN},
{.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING}, {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_BLOCK_READING_WRITING},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
// close(ioSessionFd()...) // close(ioSessionFd()...)
HRNLIBSSH2_MACRO_SHUTDOWN() HRNLIBSSH2_MACRO_SHUTDOWN()
}); });
@@ -4750,7 +4785,7 @@ testRun(void)
TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file");
TEST_ERROR( TEST_ERROR(
storageReadSftpClose((StorageReadSftp *)file->driver), FileCloseError, storageReadSftpClose((StorageReadSftp *)file->driver), FileCloseError,
"timeout closing file '" TEST_PATH "/readtest.txt'"); "timeout closing file '" TEST_PATH "/readtest.txt': libssh2 error [-37]");
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -4862,6 +4897,7 @@ testRun(void)
// storageReadSftpClose // storageReadSftpClose
{.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]"}, {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/readtest.txt\",1,0,0]"},
{.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = LIBSSH2_ERROR_ZLIB}, {.function = HRNLIBSSH2_SFTP_READ, .param = "[2]", .resultInt = LIBSSH2_ERROR_ZLIB},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
HRNLIBSSH2_MACRO_SHUTDOWN() HRNLIBSSH2_MACRO_SHUTDOWN()
}); });
@@ -4880,7 +4916,7 @@ testRun(void)
TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file"); TEST_RESULT_BOOL(ioReadOpen(storageReadIo(file)), true, "open file");
TEST_ERROR( TEST_ERROR(
storageReadSftp(((StorageReadSftp *)file->driver), outBuffer, false), FileReadError, storageReadSftp(((StorageReadSftp *)file->driver), outBuffer, false), FileReadError,
"unable to read '" TEST_PATH "/readtest.txt'"); "unable to read '" TEST_PATH "/readtest.txt': libssh2 error [-29]");
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
#else #else
@@ -5097,6 +5133,7 @@ testRun(void)
{.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"}, {.function = HRNLIBSSH2_SFTP_MKDIR_EX, .param = "[\"" TEST_PATH "/sub1\",488]"},
{.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"},
{.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, {.function = HRNLIBSSH2_SFTP_FSYNC, .resultInt = LIBSSH2_ERROR_SOCKET_SEND},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
HRNLIBSSH2_MACRO_SHUTDOWN() HRNLIBSSH2_MACRO_SHUTDOWN()
}); });
@@ -5117,7 +5154,8 @@ testRun(void)
TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file"); TEST_RESULT_VOID(ioWriteOpen(storageWriteIo(file)), "open file");
TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd"); TEST_RESULT_INT(ioWriteFd(storageWriteIo(file)), -1, "check write fd");
TEST_ERROR_FMT( TEST_ERROR_FMT(
ioWriteClose(storageWriteIo(file)), FileSyncError, "unable to sync file '%s' after write", strZ(fileNameTmp)); ioWriteClose(storageWriteIo(file)),
FileSyncError, "unable to sync file '%s' after write: libssh2 error [-7]", strZ(fileNameTmp));
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -5799,6 +5837,7 @@ testRun(void)
HRNLIBSSH2_MACRO_STARTUP(), HRNLIBSSH2_MACRO_STARTUP(),
{.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt.pgbackrest.tmp\",26,416,0]"}, {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.txt.pgbackrest.tmp\",26,416,0]"},
{.function = HRNLIBSSH2_SFTP_WRITE, .param = "[2]", .resultInt = LIBSSH2_ERROR_SOCKET_SEND}, {.function = HRNLIBSSH2_SFTP_WRITE, .param = "[2]", .resultInt = LIBSSH2_ERROR_SOCKET_SEND},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
HRNLIBSSH2_MACRO_SHUTDOWN() HRNLIBSSH2_MACRO_SHUTDOWN()
}); });
@@ -5815,7 +5854,7 @@ testRun(void)
TEST_ERROR( TEST_ERROR(
storagePutP(storageNewWriteP(storageTest, STRDEF(TEST_PATH "/test.txt")), failBuffer), FileWriteError, storagePutP(storageNewWriteP(storageTest, STRDEF(TEST_PATH "/test.txt")), failBuffer), FileWriteError,
"unable to write '" TEST_PATH "/test.txt.pgbackrest.tmp'"); "unable to write '" TEST_PATH "/test.txt.pgbackrest.tmp': libssh2 error [-7]");
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -6329,6 +6368,7 @@ testRun(void)
{.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_EAGAIN}, {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_EAGAIN},
{.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING}, {.function = HRNLIBSSH2_SESSION_BLOCK_DIRECTIONS, .resultInt = SSH2_NO_BLOCK_READING_WRITING},
{.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_BAD_SOCKET}, {.function = HRNLIBSSH2_SFTP_UNLINK_EX, .param = "[\"/missing\"]", .resultInt = LIBSSH2_ERROR_BAD_SOCKET},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
HRNLIBSSH2_MACRO_SHUTDOWN() HRNLIBSSH2_MACRO_SHUTDOWN()
}); });
@@ -6344,7 +6384,7 @@ testRun(void)
.knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true);
TEST_ERROR(storageRemoveP(storageTest, STRDEF("missing"), .errorOnMissing = true), FileRemoveError, TEST_ERROR(storageRemoveP(storageTest, STRDEF("missing"), .errorOnMissing = true), FileRemoveError,
"unable to remove '/missing'"); "unable to remove '/missing': libssh2 error [-45]");
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
@@ -6496,9 +6536,10 @@ testRun(void)
HRNLIBSSH2_MACRO_STARTUP(), HRNLIBSSH2_MACRO_STARTUP(),
{.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true, {.function = HRNLIBSSH2_SFTP_OPEN_EX, .resultNull = true,
.param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"}, .param = "[\"" TEST_PATH "/sub1/testfile.pgbackrest.tmp\",26,416,0]"},
{.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_ZLIB}, {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND},
{.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_ZLIB}, {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND},
{.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_ZLIB}, {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SOCKET_SEND},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_ERROR_NONE},
HRNLIBSSH2_MACRO_SHUTDOWN() HRNLIBSSH2_MACRO_SHUTDOWN()
}); });
@@ -6514,7 +6555,8 @@ testRun(void)
.knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true); .knownHosts = strLstNewVarLst(cfgOptionIdxLst(cfgOptRepoSftpKnownHost, repoIdx)), .write = true);
TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noSyncFile = true), "storageWriteSftpOpen ssh error"); TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noSyncFile = true), "storageWriteSftpOpen ssh error");
TEST_ERROR_FMT(ioWriteOpen(storageWriteIo(file)), FileOpenError, STORAGE_ERROR_WRITE_OPEN, strZ(fileName)); TEST_ERROR_FMT(
ioWriteOpen(storageWriteIo(file)), FileOpenError, STORAGE_ERROR_WRITE_OPEN ": libssh2 error [-7]", strZ(fileName));
memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest))); memContextFree(objMemContext((StorageSftp *)storageDriver(storageTest)));
#else #else
@@ -6540,6 +6582,7 @@ testRun(void)
{.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL},
{.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, {.function = HRNLIBSSH2_SESSION_LAST_ERRNO, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED}, {.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED},
{.function = HRNLIBSSH2_SFTP_LAST_ERROR, .resultUInt = LIBSSH2_FX_PERMISSION_DENIED},
// File missing // File missing
{.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.file\",1,0,0]", .resultNull = true, {.function = HRNLIBSSH2_SFTP_OPEN_EX, .param = "[\"" TEST_PATH "/test.file\",1,0,0]", .resultNull = true,
.resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL}, .resultInt = LIBSSH2_ERROR_SFTP_PROTOCOL},
@@ -6578,7 +6621,10 @@ testRun(void)
TEST_TITLE("permission denied"); TEST_TITLE("permission denied");
TEST_ASSIGN(file, storageNewReadP(storageTest, fileNoPerm), "new no perm read file"); TEST_ASSIGN(file, storageNewReadP(storageTest, fileNoPerm), "new no perm read file");
TEST_ERROR_FMT(ioReadOpen(storageReadIo(file)), FileOpenError, STORAGE_ERROR_READ_OPEN, strZ(fileNoPerm)); TEST_ERROR_FMT(
ioReadOpen(storageReadIo(file)),
FileOpenError,
STORAGE_ERROR_READ_OPEN ": libssh2 error [-31]: sftp error [3]", strZ(fileNoPerm));
// ------------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------------
TEST_TITLE("file missing"); TEST_TITLE("file missing");