Added a form for entering a passphrase for a private ssh key and the corresponding logic for processing a private key
This commit is contained in:
parent
f6ca22ecdd
commit
f3aef67be6
10 changed files with 161 additions and 8 deletions
|
|
@ -13,6 +13,7 @@ struct ServerCredentials
|
|||
QString hostName;
|
||||
QString userName;
|
||||
QString password;
|
||||
QString decryptedPrivateKey;
|
||||
int port = 22;
|
||||
|
||||
bool isValid() const { return !hostName.isEmpty() && !userName.isEmpty() && !password.isEmpty() && port > 0; }
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ ErrorCode ServerController::runScript(const ServerCredentials &credentials, QStr
|
|||
const std::function<ErrorCode (const QString &, libssh::Client &)> &cbReadStdOut,
|
||||
const std::function<ErrorCode (const QString &, libssh::Client &)> &cbReadStdErr) {
|
||||
|
||||
auto error = m_sshClient.connectToHost(credentials);
|
||||
auto error = m_sshClient.connectToHost(credentials, m_passphraseCallback);
|
||||
if (error != ErrorCode::NoError) {
|
||||
return error;
|
||||
}
|
||||
|
|
@ -221,7 +221,7 @@ ErrorCode ServerController::checkOpenVpnServer(DockerContainer container, const
|
|||
ErrorCode ServerController::uploadFileToHost(const ServerCredentials &credentials, const QByteArray &data, const QString &remotePath,
|
||||
libssh::SftpOverwriteMode overwriteMode)
|
||||
{
|
||||
auto error = m_sshClient.connectToHost(credentials);
|
||||
auto error = m_sshClient.connectToHost(credentials, m_passphraseCallback);
|
||||
if (error != ErrorCode::NoError) {
|
||||
return error;
|
||||
}
|
||||
|
|
@ -754,3 +754,8 @@ ErrorCode ServerController::getAlreadyInstalledContainers(const ServerCredential
|
|||
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
void ServerController::setPassphraseCallback(const std::function<QString()> &callback)
|
||||
{
|
||||
m_passphraseCallback = callback;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ public:
|
|||
|
||||
void setCancelInstallation(const bool cancel);
|
||||
ErrorCode getAlreadyInstalledContainers(const ServerCredentials &credentials, QMap<DockerContainer, QJsonObject> &installedContainers);
|
||||
|
||||
void setPassphraseCallback(const std::function<QString()> &callback);
|
||||
private:
|
||||
ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container);
|
||||
ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
|
||||
|
|
@ -86,6 +88,7 @@ private:
|
|||
|
||||
bool m_cancelInstallation = false;
|
||||
libssh::Client m_sshClient;
|
||||
std::function<QString()> m_passphraseCallback;
|
||||
signals:
|
||||
void serverIsBusy(const bool isBusy);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,18 +10,30 @@
|
|||
#endif
|
||||
|
||||
namespace libssh {
|
||||
std::function<QString()> Client::m_passphraseCallback;
|
||||
|
||||
Client::Client(QObject *parent) : QObject(parent)
|
||||
{ }
|
||||
|
||||
Client::~Client()
|
||||
{ }
|
||||
|
||||
ErrorCode Client::connectToHost(const ServerCredentials &credentials)
|
||||
int Client::callback(const char *prompt, char *buf, size_t len, int echo, int verify, void *userdata)
|
||||
{
|
||||
auto passphrase = m_passphraseCallback();
|
||||
passphrase.toStdString().copy(buf, passphrase.size() + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ErrorCode Client::connectToHost(const ServerCredentials &credentials, const std::function<QString()> &passphraseCallback)
|
||||
{
|
||||
// if (is_ssh_initialized()) {
|
||||
// qDebug() << "Failed to initialize ssh";
|
||||
// return ErrorCode::InternalError;
|
||||
// }
|
||||
|
||||
m_passphraseCallback = passphraseCallback;
|
||||
|
||||
if (m_session == nullptr) {
|
||||
m_session = ssh_new();
|
||||
|
||||
|
|
@ -52,10 +64,42 @@ namespace libssh {
|
|||
int authResult = SSH_ERROR;
|
||||
if (credentials.password.contains("BEGIN") && credentials.password.contains("PRIVATE KEY")) {
|
||||
ssh_key privateKey;
|
||||
ssh_pki_import_privkey_base64(credentials.password.toStdString().c_str(), nullptr, nullptr, nullptr, &privateKey);
|
||||
authResult = ssh_pki_import_privkey_base64(credentials.password.toStdString().c_str(), nullptr, callback, nullptr, &privateKey);
|
||||
if (authResult != SSH_OK) {
|
||||
qDebug() << ssh_get_error(m_session);
|
||||
return fromLibsshErrorCode(ssh_get_error_code(m_session));
|
||||
}
|
||||
|
||||
ssh_key publicKey;
|
||||
authResult = ssh_pki_export_privkey_to_pubkey(privateKey, &publicKey);
|
||||
if (authResult != SSH_OK) {
|
||||
qDebug() << ssh_get_error(m_session);
|
||||
return fromLibsshErrorCode(ssh_get_error_code(m_session));
|
||||
}
|
||||
authResult = ssh_userauth_try_publickey(m_session, authUsername.c_str(), publicKey);
|
||||
if (authResult != SSH_OK) {
|
||||
qDebug() << ssh_get_error(m_session);
|
||||
return fromLibsshErrorCode(ssh_get_error_code(m_session));
|
||||
}
|
||||
|
||||
authResult = ssh_userauth_publickey(m_session, authUsername.c_str(), privateKey);
|
||||
}
|
||||
else {
|
||||
if (authResult != SSH_OK) {
|
||||
qDebug() << ssh_get_error(m_session);
|
||||
return fromLibsshErrorCode(ssh_get_error_code(m_session));
|
||||
}
|
||||
|
||||
char* key = new char[65535];
|
||||
authResult = ssh_pki_export_privkey_base64(privateKey, nullptr, nullptr, nullptr, &key);
|
||||
if (authResult != SSH_OK) {
|
||||
qDebug() << ssh_get_error(m_session);
|
||||
return fromLibsshErrorCode(ssh_get_error_code(m_session));
|
||||
}
|
||||
|
||||
// credentials.decryptedPrivateKey(key);
|
||||
|
||||
ssh_key_free(publicKey);
|
||||
ssh_key_free(privateKey);
|
||||
} else {
|
||||
authResult = ssh_userauth_password(m_session, authUsername.c_str(), credentials.password.toStdString().c_str());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace libssh {
|
|||
Client(QObject *parent = nullptr);
|
||||
~Client();
|
||||
|
||||
ErrorCode connectToHost(const ServerCredentials &credentials);
|
||||
ErrorCode connectToHost(const ServerCredentials &credentials, const std::function<QString()> &passphraseCallback);
|
||||
void disconnectFromHost();
|
||||
ErrorCode executeCommand(const QString &data,
|
||||
const std::function<ErrorCode (const QString &, Client &)> &cbReadStdOut,
|
||||
|
|
@ -41,10 +41,13 @@ namespace libssh {
|
|||
ErrorCode closeSftpSession();
|
||||
ErrorCode fromLibsshErrorCode(int errorCode);
|
||||
ErrorCode fromLibsshSftpErrorCode(int errorCode);
|
||||
static int callback(const char *prompt, char *buf, size_t len, int echo, int verify, void *userdata);
|
||||
|
||||
ssh_session m_session = nullptr;
|
||||
ssh_channel m_channel = nullptr;
|
||||
sftp_session m_sftpSession = nullptr;
|
||||
|
||||
static std::function<QString()> m_passphraseCallback;
|
||||
signals:
|
||||
void writeToChannelFinished();
|
||||
void sftpFileCopyFinished();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue