parent
840c388ab9
commit
6b6a76d2cc
8 changed files with 98 additions and 141 deletions
|
|
@ -76,7 +76,7 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co
|
||||||
|
|
||||||
if (connData.caCert.isEmpty() || connData.clientCert.isEmpty() || connData.taKey.isEmpty()) {
|
if (connData.caCert.isEmpty() || connData.clientCert.isEmpty() || connData.taKey.isEmpty()) {
|
||||||
if (errorCode)
|
if (errorCode)
|
||||||
*errorCode = ErrorCode::SshSftpFailureError;
|
*errorCode = ErrorCode::SshScpFailureError;
|
||||||
}
|
}
|
||||||
|
|
||||||
return connData;
|
return connData;
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon
|
||||||
.arg(connData.clientPubKey, connData.pskKey, connData.clientIP);
|
.arg(connData.clientPubKey, connData.pskKey, connData.clientIP);
|
||||||
|
|
||||||
e = serverController.uploadTextFileToContainer(container, credentials, configPart, m_serverConfigPath,
|
e = serverController.uploadTextFileToContainer(container, credentials, configPart, m_serverConfigPath,
|
||||||
libssh::SftpOverwriteMode::SftpAppendToExisting);
|
libssh::ScpOverwriteMode::ScpAppendToExisting);
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
if (errorCode)
|
if (errorCode)
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ ServerController::runContainerScript(const ServerCredentials &credentials, Docke
|
||||||
|
|
||||||
ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container, const ServerCredentials &credentials,
|
ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container, const ServerCredentials &credentials,
|
||||||
const QString &file, const QString &path,
|
const QString &file, const QString &path,
|
||||||
libssh::SftpOverwriteMode overwriteMode)
|
libssh::ScpOverwriteMode overwriteMode)
|
||||||
{
|
{
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
QString tmpFileName = QString("/tmp/%1.tmp").arg(Utils::getRandomString(16));
|
QString tmpFileName = QString("/tmp/%1.tmp").arg(Utils::getRandomString(16));
|
||||||
|
|
@ -139,7 +139,7 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
||||||
if (e)
|
if (e)
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
if (overwriteMode == libssh::SftpOverwriteMode::SftpOverwriteExisting) {
|
if (overwriteMode == libssh::ScpOverwriteMode::ScpOverwriteExisting) {
|
||||||
e = runScript(credentials,
|
e = runScript(credentials,
|
||||||
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(path),
|
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(path),
|
||||||
genVarsForScript(credentials, container)),
|
genVarsForScript(credentials, container)),
|
||||||
|
|
@ -147,7 +147,7 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
|
||||||
|
|
||||||
if (e)
|
if (e)
|
||||||
return e;
|
return e;
|
||||||
} else if (overwriteMode == libssh::SftpOverwriteMode::SftpAppendToExisting) {
|
} else if (overwriteMode == libssh::ScpOverwriteMode::ScpAppendToExisting) {
|
||||||
e = runScript(credentials,
|
e = runScript(credentials,
|
||||||
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(tmpFileName),
|
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(tmpFileName),
|
||||||
genVarsForScript(credentials, container)),
|
genVarsForScript(credentials, container)),
|
||||||
|
|
@ -199,7 +199,7 @@ QByteArray ServerController::getTextFileFromContainer(DockerContainer container,
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode ServerController::uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data,
|
ErrorCode ServerController::uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data,
|
||||||
const QString &remotePath, libssh::SftpOverwriteMode overwriteMode)
|
const QString &remotePath, libssh::ScpOverwriteMode overwriteMode)
|
||||||
{
|
{
|
||||||
auto error = m_sshClient.connectToHost(credentials);
|
auto error = m_sshClient.connectToHost(credentials);
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
|
|
@ -211,7 +211,7 @@ ErrorCode ServerController::uploadFileToHost(const ServerCredentials &credential
|
||||||
localFile.write(data);
|
localFile.write(data);
|
||||||
localFile.close();
|
localFile.close();
|
||||||
|
|
||||||
error = m_sshClient.sftpFileCopy(overwriteMode, localFile.fileName(), remotePath, "non_desc");
|
error = m_sshClient.scpFileCopy(overwriteMode, localFile.fileName(), remotePath, "non_desc");
|
||||||
|
|
||||||
if (error != ErrorCode::NoError) {
|
if (error != ErrorCode::NoError) {
|
||||||
return error;
|
return error;
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ public:
|
||||||
|
|
||||||
ErrorCode uploadTextFileToContainer(
|
ErrorCode uploadTextFileToContainer(
|
||||||
DockerContainer container, const ServerCredentials &credentials, const QString &file, const QString &path,
|
DockerContainer container, const ServerCredentials &credentials, const QString &file, const QString &path,
|
||||||
libssh::SftpOverwriteMode overwriteMode = libssh::SftpOverwriteMode::SftpOverwriteExisting);
|
libssh::ScpOverwriteMode overwriteMode = libssh::ScpOverwriteMode::ScpOverwriteExisting);
|
||||||
QByteArray getTextFileFromContainer(DockerContainer container, const ServerCredentials &credentials,
|
QByteArray getTextFileFromContainer(DockerContainer container, const ServerCredentials &credentials,
|
||||||
const QString &path, ErrorCode *errorCode = nullptr);
|
const QString &path, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
|
|
@ -80,7 +80,7 @@ private:
|
||||||
ErrorCode isServerDpkgBusy(const ServerCredentials &credentials, DockerContainer container);
|
ErrorCode isServerDpkgBusy(const ServerCredentials &credentials, DockerContainer container);
|
||||||
|
|
||||||
ErrorCode uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, const QString &remotePath,
|
ErrorCode uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, const QString &remotePath,
|
||||||
libssh::SftpOverwriteMode overwriteMode = libssh::SftpOverwriteMode::SftpOverwriteExisting);
|
libssh::ScpOverwriteMode overwriteMode = libssh::ScpOverwriteMode::ScpOverwriteExisting);
|
||||||
|
|
||||||
ErrorCode setupServerFirewall(const ServerCredentials &credentials);
|
ErrorCode setupServerFirewall(const ServerCredentials &credentials);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,25 +46,12 @@ namespace amnezia
|
||||||
SshPrivateKeyFormatError = 304,
|
SshPrivateKeyFormatError = 304,
|
||||||
SshTimeoutError = 305,
|
SshTimeoutError = 305,
|
||||||
|
|
||||||
// Ssh sftp errors
|
// Ssh scp errors
|
||||||
SshSftpEofError = 400,
|
SshScpFailureError = 400,
|
||||||
SshSftpNoSuchFileError = 401,
|
|
||||||
SshSftpPermissionDeniedError = 402,
|
|
||||||
SshSftpFailureError = 403,
|
|
||||||
SshSftpBadMessageError = 404,
|
|
||||||
SshSftpNoConnectionError = 405,
|
|
||||||
SshSftpConnectionLostError = 406,
|
|
||||||
SshSftpOpUnsupportedError = 407,
|
|
||||||
SshSftpInvalidHandleError = 408,
|
|
||||||
SshSftpNoSuchPathError = 409,
|
|
||||||
SshSftpFileAlreadyExistsError = 410,
|
|
||||||
SshSftpWriteProtectError = 411,
|
|
||||||
SshSftpNoMediaError = 412,
|
|
||||||
|
|
||||||
// Local errors
|
// Local errors
|
||||||
OpenVpnConfigMissing = 500,
|
OpenVpnConfigMissing = 500,
|
||||||
OpenVpnManagementServerError = 501,
|
OpenVpnManagementServerError = 501,
|
||||||
ConfigMissing = 502,
|
|
||||||
|
|
||||||
// Distro errors
|
// Distro errors
|
||||||
OpenVpnExecutableMissing = 600,
|
OpenVpnExecutableMissing = 600,
|
||||||
|
|
@ -92,7 +79,15 @@ namespace amnezia
|
||||||
|
|
||||||
// Api errors
|
// Api errors
|
||||||
ApiConfigDownloadError = 1100,
|
ApiConfigDownloadError = 1100,
|
||||||
ApiConfigAlreadyAdded = 1101
|
ApiConfigAlreadyAdded = 1101,
|
||||||
|
|
||||||
|
// QFile errors
|
||||||
|
OpenError = 1200,
|
||||||
|
ReadError = 1201,
|
||||||
|
PermissionsError = 1202,
|
||||||
|
UnspecifiedError = 1203,
|
||||||
|
FatalError = 1204,
|
||||||
|
AbortError = 1205
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace amnezia
|
} // namespace amnezia
|
||||||
|
|
|
||||||
|
|
@ -28,20 +28,8 @@ QString errorString(ErrorCode code) {
|
||||||
case(SshPrivateKeyFormatError): errorMessage = QObject::tr("The selected private key format is not supported, use openssh ED25519 key types or PEM key types"); break;
|
case(SshPrivateKeyFormatError): errorMessage = QObject::tr("The selected private key format is not supported, use openssh ED25519 key types or PEM key types"); break;
|
||||||
case(SshTimeoutError): errorMessage = QObject::tr("Timeout connecting to server"); break;
|
case(SshTimeoutError): errorMessage = QObject::tr("Timeout connecting to server"); break;
|
||||||
|
|
||||||
// Libssh sftp errors
|
// Ssh scp errors
|
||||||
case(SshSftpEofError): errorMessage = QObject::tr("Sftp error: End-of-file encountered"); break;
|
case(SshScpFailureError): errorMessage = QObject::tr("Scp error: Generic failure"); break;
|
||||||
case(SshSftpNoSuchFileError): errorMessage = QObject::tr("Sftp error: File does not exist"); break;
|
|
||||||
case(SshSftpPermissionDeniedError): errorMessage = QObject::tr("Sftp error: Permission denied"); break;
|
|
||||||
case(SshSftpFailureError): errorMessage = QObject::tr("Sftp error: Generic failure"); break;
|
|
||||||
case(SshSftpBadMessageError): errorMessage = QObject::tr("Sftp error: Garbage received from server"); break;
|
|
||||||
case(SshSftpNoConnectionError): errorMessage = QObject::tr("Sftp error: No connection has been set up"); break;
|
|
||||||
case(SshSftpConnectionLostError): errorMessage = QObject::tr("Sftp error: There was a connection, but we lost it"); break;
|
|
||||||
case(SshSftpOpUnsupportedError): errorMessage = QObject::tr("Sftp error: Operation not supported by libssh yet"); break;
|
|
||||||
case(SshSftpInvalidHandleError): errorMessage = QObject::tr("Sftp error: Invalid file handle"); break;
|
|
||||||
case(SshSftpNoSuchPathError): errorMessage = QObject::tr("Sftp error: No such file or directory path exists"); break;
|
|
||||||
case(SshSftpFileAlreadyExistsError): errorMessage = QObject::tr("Sftp error: An attempt to create an already existing file or directory has been made"); break;
|
|
||||||
case(SshSftpWriteProtectError): errorMessage = QObject::tr("Sftp error: Write-protected filesystem"); break;
|
|
||||||
case(SshSftpNoMediaError): errorMessage = QObject::tr("Sftp error: No media was in remote drive"); break;
|
|
||||||
|
|
||||||
// Local errors
|
// Local errors
|
||||||
case (OpenVpnConfigMissing): errorMessage = QObject::tr("OpenVPN config missing"); break;
|
case (OpenVpnConfigMissing): errorMessage = QObject::tr("OpenVPN config missing"); break;
|
||||||
|
|
@ -68,6 +56,14 @@ QString errorString(ErrorCode code) {
|
||||||
case (ApiConfigDownloadError): errorMessage = QObject::tr("Error when retrieving configuration from API"); break;
|
case (ApiConfigDownloadError): errorMessage = QObject::tr("Error when retrieving configuration from API"); break;
|
||||||
case (ApiConfigAlreadyAdded): errorMessage = QObject::tr("This config has already been added to the application"); break;
|
case (ApiConfigAlreadyAdded): errorMessage = QObject::tr("This config has already been added to the application"); break;
|
||||||
|
|
||||||
|
// QFile errors
|
||||||
|
case(OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;
|
||||||
|
case(ReadError): errorMessage = QObject::tr("QFile error: An error occurred when reading from the file"); break;
|
||||||
|
case(PermissionsError): errorMessage = QObject::tr("QFile error: The file could not be accessed"); break;
|
||||||
|
case(UnspecifiedError): errorMessage = QObject::tr("QFile error: An unspecified error occurred"); break;
|
||||||
|
case(FatalError): errorMessage = QObject::tr("QFile error: A fatal error occurred"); break;
|
||||||
|
case(AbortError): errorMessage = QObject::tr("QFile error: The operation was aborted"); break;
|
||||||
|
|
||||||
case(InternalError):
|
case(InternalError):
|
||||||
default:
|
default:
|
||||||
errorMessage = QObject::tr("Internal error"); break;
|
errorMessage = QObject::tr("Internal error"); break;
|
||||||
|
|
|
||||||
|
|
@ -10,16 +10,10 @@ const uint32_t S_IRWXU = 0644;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace libssh {
|
namespace libssh {
|
||||||
const QString libsshTimeoutError = "Timeout connecting to";
|
constexpr auto libsshTimeoutError{"Timeout connecting to"};
|
||||||
|
|
||||||
std::function<QString()> Client::m_passphraseCallback;
|
std::function<QString()> Client::m_passphraseCallback;
|
||||||
|
|
||||||
Client::Client(QObject *parent) : QObject(parent)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
Client::~Client()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
int Client::callback(const char *prompt, char *buf, size_t len, int echo, int verify, void *userdata)
|
int Client::callback(const char *prompt, char *buf, size_t len, int echo, int verify, void *userdata)
|
||||||
{
|
{
|
||||||
auto passphrase = m_passphraseCallback();
|
auto passphrase = m_passphraseCallback();
|
||||||
|
|
@ -171,13 +165,13 @@ namespace libssh {
|
||||||
return ErrorCode::NoError;
|
return ErrorCode::NoError;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto error = readOutput(false);
|
auto errorCode = readOutput(false);
|
||||||
if (error != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return error;
|
return errorCode;
|
||||||
}
|
}
|
||||||
error = readOutput(true);
|
errorCode = readOutput(true);
|
||||||
if (error != ErrorCode::NoError) {
|
if (errorCode != ErrorCode::NoError) {
|
||||||
return error;
|
return errorCode;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return closeChannel();
|
return closeChannel();
|
||||||
|
|
@ -222,100 +216,79 @@ namespace libssh {
|
||||||
return fromLibsshErrorCode();
|
return fromLibsshErrorCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode Client::sftpFileCopy(const SftpOverwriteMode overwriteMode, const QString& localPath, const QString& remotePath, const QString &fileDesc)
|
ErrorCode Client::scpFileCopy(const ScpOverwriteMode overwriteMode, const QString& localPath, const QString& remotePath, const QString &fileDesc)
|
||||||
{
|
{
|
||||||
m_sftpSession = sftp_new(m_session);
|
m_scpSession = ssh_scp_new(m_session, SSH_SCP_WRITE, remotePath.toStdString().c_str());
|
||||||
|
|
||||||
if (m_sftpSession == nullptr) {
|
if (m_scpSession == nullptr) {
|
||||||
return closeSftpSession();
|
return fromLibsshErrorCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = sftp_init(m_sftpSession);
|
if (ssh_scp_init(m_scpSession) != SSH_OK) {
|
||||||
|
auto errorCode = fromLibsshErrorCode();
|
||||||
if (result != SSH_OK) {
|
closeScpSession();
|
||||||
return closeSftpSession();
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
QFutureWatcher<ErrorCode> watcher;
|
QFutureWatcher<ErrorCode> watcher;
|
||||||
connect(&watcher, &QFutureWatcher<ErrorCode>::finished, this, &Client::sftpFileCopyFinished);
|
connect(&watcher, &QFutureWatcher<ErrorCode>::finished, this, &Client::scpFileCopyFinished);
|
||||||
|
|
||||||
QFuture<ErrorCode> future = QtConcurrent::run([this, overwriteMode, &localPath, &remotePath, &fileDesc]() {
|
QFuture<ErrorCode> future = QtConcurrent::run([this, overwriteMode, &localPath, &remotePath, &fileDesc]() {
|
||||||
int accessType = O_WRONLY | O_CREAT | overwriteMode;
|
const int accessType = O_WRONLY | O_CREAT | overwriteMode;
|
||||||
sftp_file file;
|
const int localFileSize = QFileInfo(localPath).size();
|
||||||
const size_t bufferSize = 16384;
|
|
||||||
char buffer[bufferSize];
|
|
||||||
|
|
||||||
file = sftp_open(m_sftpSession, remotePath.toStdString().c_str(), accessType, S_IRWXU);
|
int result = ssh_scp_push_file(m_scpSession, remotePath.toStdString().c_str(), localFileSize, accessType);
|
||||||
|
if (result != SSH_OK) {
|
||||||
if (file == nullptr) {
|
return fromLibsshErrorCode();
|
||||||
return closeSftpSession();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int localFileSize = QFileInfo(localPath).size();
|
|
||||||
int chunksCount = localFileSize / (bufferSize);
|
|
||||||
|
|
||||||
QFile fin(localPath);
|
QFile fin(localPath);
|
||||||
|
|
||||||
if (fin.open(QIODevice::ReadOnly)) {
|
if (fin.open(QIODevice::ReadOnly)) {
|
||||||
for (int currentChunkId = 0; currentChunkId < chunksCount; currentChunkId++) {
|
constexpr size_t bufferSize = 16384;
|
||||||
QByteArray chunk = fin.read(bufferSize);
|
int transferred = 0;
|
||||||
if (chunk.size() != bufferSize) return ErrorCode::SshSftpEofError;
|
int currentChunkSize = bufferSize;
|
||||||
|
|
||||||
int bytesWritten = sftp_write(file, chunk.data(), chunk.size());
|
while (transferred < localFileSize) {
|
||||||
|
|
||||||
if (bytesWritten != chunk.size()) {
|
// Last Chunk
|
||||||
fin.close();
|
if ((localFileSize - transferred) < bufferSize) {
|
||||||
sftp_close(file);
|
currentChunkSize = localFileSize % bufferSize;
|
||||||
return closeSftpSession();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int lastChunkSize = localFileSize % bufferSize;
|
QByteArray chunk = fin.read(currentChunkSize);
|
||||||
|
if (chunk.size() != currentChunkSize) {
|
||||||
if (lastChunkSize != 0) {
|
return fromFileErrorCode(fin.error());
|
||||||
QByteArray lastChunk = fin.read(lastChunkSize);
|
|
||||||
if (lastChunk.size() != lastChunkSize) return ErrorCode::SshSftpEofError;
|
|
||||||
|
|
||||||
int bytesWritten = sftp_write(file, lastChunk.data(), lastChunkSize);
|
|
||||||
|
|
||||||
if (bytesWritten != lastChunkSize) {
|
|
||||||
fin.close();
|
|
||||||
sftp_close(file);
|
|
||||||
return closeSftpSession();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = ssh_scp_write(m_scpSession, chunk.data(), chunk.size());
|
||||||
|
if (result != SSH_OK) {
|
||||||
|
return fromLibsshErrorCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
transferred += currentChunkSize;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sftp_close(file);
|
return fromFileErrorCode(fin.error());
|
||||||
return closeSftpSession();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fin.close();
|
return ErrorCode::NoError;
|
||||||
|
|
||||||
int result = sftp_close(file);
|
|
||||||
if (result != SSH_OK) {
|
|
||||||
return closeSftpSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
return closeSftpSession();
|
|
||||||
});
|
});
|
||||||
watcher.setFuture(future);
|
watcher.setFuture(future);
|
||||||
|
|
||||||
QEventLoop wait;
|
QEventLoop wait;
|
||||||
QObject::connect(this, &Client::sftpFileCopyFinished, &wait, &QEventLoop::quit);
|
QObject::connect(this, &Client::scpFileCopyFinished, &wait, &QEventLoop::quit);
|
||||||
wait.exec();
|
wait.exec();
|
||||||
|
|
||||||
|
closeScpSession();
|
||||||
return watcher.result();
|
return watcher.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode Client::closeSftpSession()
|
void Client::closeScpSession()
|
||||||
{
|
{
|
||||||
auto errorCode = fromLibsshSftpErrorCode(sftp_get_error(m_sftpSession));
|
if (m_scpSession != nullptr) {
|
||||||
if (m_sftpSession != nullptr) {
|
ssh_scp_free(m_scpSession);
|
||||||
sftp_free(m_sftpSession);
|
m_scpSession = nullptr;
|
||||||
m_sftpSession = nullptr;
|
|
||||||
}
|
}
|
||||||
qCritical() << ssh_get_error(m_session);
|
|
||||||
return errorCode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode Client::fromLibsshErrorCode()
|
ErrorCode Client::fromLibsshErrorCode()
|
||||||
|
|
@ -337,24 +310,17 @@ namespace libssh {
|
||||||
default: return ErrorCode::SshInternalError;
|
default: return ErrorCode::SshInternalError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ErrorCode Client::fromLibsshSftpErrorCode(int errorCode)
|
|
||||||
|
ErrorCode Client::fromFileErrorCode(QFileDevice::FileError fileError)
|
||||||
{
|
{
|
||||||
switch (errorCode) {
|
switch (fileError) {
|
||||||
case(SSH_FX_OK): return ErrorCode::NoError;
|
case QFileDevice::NoError: return ErrorCode::NoError;
|
||||||
case(SSH_FX_EOF): return ErrorCode::SshSftpEofError;
|
case QFileDevice::ReadError: return ErrorCode::ReadError;
|
||||||
case(SSH_FX_NO_SUCH_FILE): return ErrorCode::SshSftpNoSuchFileError;
|
case QFileDevice::OpenError: return ErrorCode::OpenError;
|
||||||
case(SSH_FX_PERMISSION_DENIED): return ErrorCode::SshSftpPermissionDeniedError;
|
case QFileDevice::PermissionsError: return ErrorCode::PermissionsError;
|
||||||
case(SSH_FX_FAILURE): return ErrorCode::SshSftpFailureError;
|
case QFileDevice::FatalError: return ErrorCode::FatalError;
|
||||||
case(SSH_FX_BAD_MESSAGE): return ErrorCode::SshSftpBadMessageError;
|
case QFileDevice::AbortError: return ErrorCode::AbortError;
|
||||||
case(SSH_FX_NO_CONNECTION): return ErrorCode::SshSftpNoConnectionError;
|
default: return ErrorCode::UnspecifiedError;
|
||||||
case(SSH_FX_CONNECTION_LOST): return ErrorCode::SshSftpConnectionLostError;
|
|
||||||
case(SSH_FX_OP_UNSUPPORTED): return ErrorCode::SshSftpOpUnsupportedError;
|
|
||||||
case(SSH_FX_INVALID_HANDLE): return ErrorCode::SshSftpInvalidHandleError;
|
|
||||||
case(SSH_FX_NO_SUCH_PATH): return ErrorCode::SshSftpNoSuchPathError;
|
|
||||||
case(SSH_FX_FILE_ALREADY_EXISTS): return ErrorCode::SshSftpFileAlreadyExistsError;
|
|
||||||
case(SSH_FX_WRITE_PROTECT): return ErrorCode::SshSftpWriteProtectError;
|
|
||||||
case(SSH_FX_NO_MEDIA): return ErrorCode::SshSftpNoMediaError;
|
|
||||||
default: return ErrorCode::SshSftpFailureError;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,29 +2,29 @@
|
||||||
#define SSHCLIENT_H
|
#define SSHCLIENT_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include <libssh/libssh.h>
|
#include <libssh/libssh.h>
|
||||||
#include <libssh/sftp.h>
|
|
||||||
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
using namespace amnezia;
|
using namespace amnezia;
|
||||||
|
|
||||||
namespace libssh {
|
namespace libssh {
|
||||||
enum SftpOverwriteMode {
|
enum ScpOverwriteMode {
|
||||||
/*! Overwrite any existing files */
|
/*! Overwrite any existing files */
|
||||||
SftpOverwriteExisting = O_TRUNC,
|
ScpOverwriteExisting = O_TRUNC,
|
||||||
/*! Append new content if the file already exists */
|
/*! Append new content if the file already exists */
|
||||||
SftpAppendToExisting = O_APPEND
|
ScpAppendToExisting = O_APPEND
|
||||||
};
|
};
|
||||||
class Client : public QObject
|
class Client : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Client(QObject *parent = nullptr);
|
Client() = default;
|
||||||
~Client();
|
~Client() = default;
|
||||||
|
|
||||||
ErrorCode connectToHost(const ServerCredentials &credentials);
|
ErrorCode connectToHost(const ServerCredentials &credentials);
|
||||||
void disconnectFromHost();
|
void disconnectFromHost();
|
||||||
|
|
@ -32,26 +32,26 @@ namespace libssh {
|
||||||
const std::function<ErrorCode (const QString &, Client &)> &cbReadStdOut,
|
const std::function<ErrorCode (const QString &, Client &)> &cbReadStdOut,
|
||||||
const std::function<ErrorCode (const QString &, Client &)> &cbReadStdErr);
|
const std::function<ErrorCode (const QString &, Client &)> &cbReadStdErr);
|
||||||
ErrorCode writeResponse(const QString &data);
|
ErrorCode writeResponse(const QString &data);
|
||||||
ErrorCode sftpFileCopy(const SftpOverwriteMode overwriteMode,
|
ErrorCode scpFileCopy(const ScpOverwriteMode overwriteMode,
|
||||||
const QString &localPath,
|
const QString &localPath,
|
||||||
const QString &remotePath,
|
const QString &remotePath,
|
||||||
const QString &fileDesc);
|
const QString &fileDesc);
|
||||||
ErrorCode getDecryptedPrivateKey(const ServerCredentials &credentials, QString &decryptedPrivateKey, const std::function<QString()> &passphraseCallback);
|
ErrorCode getDecryptedPrivateKey(const ServerCredentials &credentials, QString &decryptedPrivateKey, const std::function<QString()> &passphraseCallback);
|
||||||
private:
|
private:
|
||||||
ErrorCode closeChannel();
|
ErrorCode closeChannel();
|
||||||
ErrorCode closeSftpSession();
|
void closeScpSession();
|
||||||
ErrorCode fromLibsshErrorCode();
|
ErrorCode fromLibsshErrorCode();
|
||||||
ErrorCode fromLibsshSftpErrorCode(int errorCode);
|
ErrorCode fromFileErrorCode(QFileDevice::FileError fileError);
|
||||||
static int callback(const char *prompt, char *buf, size_t len, int echo, int verify, void *userdata);
|
static int callback(const char *prompt, char *buf, size_t len, int echo, int verify, void *userdata);
|
||||||
|
|
||||||
ssh_session m_session = nullptr;
|
ssh_session m_session = nullptr;
|
||||||
ssh_channel m_channel = nullptr;
|
ssh_channel m_channel = nullptr;
|
||||||
sftp_session m_sftpSession = nullptr;
|
ssh_scp m_scpSession = nullptr;
|
||||||
|
|
||||||
static std::function<QString()> m_passphraseCallback;
|
static std::function<QString()> m_passphraseCallback;
|
||||||
signals:
|
signals:
|
||||||
void writeToChannelFinished();
|
void writeToChannelFinished();
|
||||||
void sftpFileCopyFinished();
|
void scpFileCopyFinished();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue