made libssh::ssh_connect a non-blocking feature

- extended error handling when connecting via ssh
This commit is contained in:
vladimir.kuznetsov 2023-06-10 05:25:41 +03:00
parent c3f39ad24d
commit cd3263db50
10 changed files with 54 additions and 34 deletions

View file

@ -10,6 +10,8 @@ const uint32_t S_IRWXU = 0644;
#endif
namespace libssh {
const QString libsshTimeoutError = "Timeout connecting to";
std::function<QString()> Client::m_passphraseCallback;
Client::Client(QObject *parent) : QObject(parent)
@ -45,11 +47,20 @@ namespace libssh {
ssh_options_set(m_session, SSH_OPTIONS_USER, hostUsername.c_str());
ssh_options_set(m_session, SSH_OPTIONS_LOG_VERBOSITY, &logVerbosity);
int connectionResult = ssh_connect(m_session);
QFutureWatcher<int> watcher;
QFuture<int> future = QtConcurrent::run([this]() {
return ssh_connect(m_session);
});
QEventLoop wait;
connect(&watcher, &QFutureWatcher<ErrorCode>::finished, &wait, &QEventLoop::quit);
watcher.setFuture(future);
wait.exec();
int connectionResult = watcher.result();
if (connectionResult != SSH_OK) {
qDebug() << ssh_get_error(m_session);
return fromLibsshErrorCode(ssh_get_error_code(m_session));
return fromLibsshErrorCode();
}
std::string authUsername = credentials.userName.toStdString();
@ -78,8 +89,8 @@ namespace libssh {
ssh_key_free(privateKey);
}
if (authResult != SSH_OK) {
qDebug() << ssh_get_error(m_session);
ErrorCode errorCode = fromLibsshErrorCode(ssh_get_error_code(m_session));
qCritical() << ssh_get_error(m_session);
ErrorCode errorCode = fromLibsshErrorCode();
if (errorCode == ErrorCode::NoError) {
errorCode = ErrorCode::SshPrivateKeyFormatError;
}
@ -88,8 +99,7 @@ namespace libssh {
} else {
authResult = ssh_userauth_password(m_session, authUsername.c_str(), credentials.secretData.toStdString().c_str());
if (authResult != SSH_OK) {
qDebug() << ssh_get_error(m_session);
return fromLibsshErrorCode(ssh_get_error_code(m_session));
return fromLibsshErrorCode();
}
}
}
@ -188,16 +198,15 @@ namespace libssh {
ErrorCode Client::writeResponse(const QString &data)
{
if (m_channel == nullptr) {
qDebug() << "ssh channel not initialized";
return fromLibsshErrorCode(ssh_get_error_code(m_session));
qCritical() << "ssh channel not initialized";
return fromLibsshErrorCode();
}
int bytesWritten = ssh_channel_write(m_channel, data.toUtf8(), (uint32_t)data.size());
if (bytesWritten == data.size() && ssh_channel_write(m_channel, "\n", 1)) {
return fromLibsshErrorCode(ssh_get_error_code(m_session));
return fromLibsshErrorCode();
}
qDebug() << ssh_get_error(m_session);
return fromLibsshErrorCode(ssh_get_error_code(m_session));
return fromLibsshErrorCode();
}
ErrorCode Client::closeChannel()
@ -212,8 +221,7 @@ namespace libssh {
ssh_channel_free(m_channel);
m_channel = nullptr;
}
qDebug() << ssh_get_error(m_session);
return fromLibsshErrorCode(ssh_get_error_code(m_session));
return fromLibsshErrorCode();
}
ErrorCode Client::sftpFileCopy(const SftpOverwriteMode overwriteMode, const std::string& localPath, const std::string& remotePath, const std::string& fileDesc)
@ -312,12 +320,21 @@ namespace libssh {
sftp_free(m_sftpSession);
m_sftpSession = nullptr;
}
qDebug() << ssh_get_error(m_session);
qCritical() << ssh_get_error(m_session);
return errorCode;
}
ErrorCode Client::fromLibsshErrorCode(int errorCode)
ErrorCode Client::fromLibsshErrorCode()
{
int errorCode = ssh_get_error_code(m_session);
if (errorCode != SSH_NO_ERROR) {
QString errorMessage = ssh_get_error(m_session);
qCritical() << errorMessage;
if (errorMessage.contains(libsshTimeoutError)) {
return ErrorCode::SshTimeoutError;
}
}
switch (errorCode) {
case(SSH_NO_ERROR): return ErrorCode::NoError;
case(SSH_REQUEST_DENIED): return ErrorCode::SshRequsetDeniedError;