added private key export without password to client config
This commit is contained in:
parent
f3aef67be6
commit
5e099f522e
10 changed files with 76 additions and 56 deletions
|
@ -13,7 +13,6 @@ 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; }
|
||||
|
@ -36,6 +35,7 @@ enum ErrorCode
|
|||
|
||||
// Ssh connection errors
|
||||
SshRequsetDeniedError, SshInterruptedError, SshInternalError,
|
||||
SshPrivateKeyError,
|
||||
|
||||
// Ssh sftp errors
|
||||
SshSftpEofError, SshSftpNoSuchFileError, SshSftpPermissionDeniedError,
|
||||
|
|
|
@ -21,6 +21,7 @@ QString errorString(ErrorCode code){
|
|||
case(SshRequsetDeniedError): return QObject::tr("Ssh request was denied");
|
||||
case(SshInterruptedError): return QObject::tr("Ssh request was interrupted");
|
||||
case(SshInternalError): return QObject::tr("Ssh internal error");
|
||||
case(SshPrivateKeyError): return QObject::tr("Invalid private key or invalid passphrase entered");
|
||||
|
||||
// Libssh sftp errors
|
||||
case(SshSftpEofError): return QObject::tr("Sftp error: End-of-file encountered");
|
||||
|
|
|
@ -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, m_passphraseCallback);
|
||||
auto error = m_sshClient.connectToHost(credentials);
|
||||
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, m_passphraseCallback);
|
||||
auto error = m_sshClient.connectToHost(credentials);
|
||||
if (error != ErrorCode::NoError) {
|
||||
return error;
|
||||
}
|
||||
|
@ -757,5 +757,11 @@ ErrorCode ServerController::getAlreadyInstalledContainers(const ServerCredential
|
|||
|
||||
void ServerController::setPassphraseCallback(const std::function<QString()> &callback)
|
||||
{
|
||||
m_passphraseCallback = callback;
|
||||
m_sshClient.setPassphraseCallback(callback);
|
||||
}
|
||||
|
||||
ErrorCode ServerController::getDecryptedPrivateKey(const ServerCredentials &credentials, QString &decryptedPrivateKey)
|
||||
{
|
||||
auto error = m_sshClient.getDecryptedPrivateKey(credentials, decryptedPrivateKey);
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
ErrorCode getAlreadyInstalledContainers(const ServerCredentials &credentials, QMap<DockerContainer, QJsonObject> &installedContainers);
|
||||
|
||||
void setPassphraseCallback(const std::function<QString()> &callback);
|
||||
ErrorCode getDecryptedPrivateKey(const ServerCredentials &credentials, QString &decryptedPrivateKey);
|
||||
private:
|
||||
ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container);
|
||||
ErrorCode prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
|
||||
|
@ -88,7 +89,6 @@ private:
|
|||
|
||||
bool m_cancelInstallation = false;
|
||||
libssh::Client m_sshClient;
|
||||
std::function<QString()> m_passphraseCallback;
|
||||
signals:
|
||||
void serverIsBusy(const bool isBusy);
|
||||
};
|
||||
|
|
|
@ -25,15 +25,8 @@ namespace libssh {
|
|||
return 0;
|
||||
}
|
||||
|
||||
ErrorCode Client::connectToHost(const ServerCredentials &credentials, const std::function<QString()> &passphraseCallback)
|
||||
ErrorCode Client::connectToHost(const ServerCredentials &credentials)
|
||||
{
|
||||
// if (is_ssh_initialized()) {
|
||||
// qDebug() << "Failed to initialize ssh";
|
||||
// return ErrorCode::InternalError;
|
||||
// }
|
||||
|
||||
m_passphraseCallback = passphraseCallback;
|
||||
|
||||
if (m_session == nullptr) {
|
||||
m_session = ssh_new();
|
||||
|
||||
|
@ -64,39 +57,20 @@ namespace libssh {
|
|||
int authResult = SSH_ERROR;
|
||||
if (credentials.password.contains("BEGIN") && credentials.password.contains("PRIVATE KEY")) {
|
||||
ssh_key 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_pki_import_privkey_base64(credentials.password.toStdString().c_str(), nullptr, callback, nullptr, &privateKey);
|
||||
if (authResult == SSH_OK) {
|
||||
authResult = ssh_pki_export_privkey_to_pubkey(privateKey, &publicKey);
|
||||
}
|
||||
|
||||
authResult = ssh_userauth_publickey(m_session, authUsername.c_str(), privateKey);
|
||||
if (authResult != SSH_OK) {
|
||||
qDebug() << ssh_get_error(m_session);
|
||||
return fromLibsshErrorCode(ssh_get_error_code(m_session));
|
||||
if (authResult == SSH_OK) {
|
||||
authResult = ssh_userauth_try_publickey(m_session, authUsername.c_str(), publicKey);
|
||||
}
|
||||
|
||||
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));
|
||||
if (authResult == SSH_OK) {
|
||||
authResult = ssh_userauth_publickey(m_session, authUsername.c_str(), privateKey);
|
||||
}
|
||||
|
||||
// credentials.decryptedPrivateKey(key);
|
||||
|
||||
ssh_key_free(publicKey);
|
||||
ssh_key_free(privateKey);
|
||||
} else {
|
||||
|
@ -363,4 +337,35 @@ namespace libssh {
|
|||
default: return ErrorCode::SshSftpFailureError;
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode Client::getDecryptedPrivateKey(const ServerCredentials &credentials, QString &decryptedPrivateKey)
|
||||
{
|
||||
int authResult = SSH_ERROR;
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
|
||||
ssh_key privateKey;
|
||||
authResult = ssh_pki_import_privkey_base64(credentials.password.toStdString().c_str(), nullptr, callback, nullptr, &privateKey);
|
||||
if (authResult == SSH_OK) {
|
||||
char* key = new char[65535];
|
||||
|
||||
authResult = ssh_pki_export_privkey_base64(privateKey, nullptr, nullptr, nullptr, &key);
|
||||
decryptedPrivateKey = key;
|
||||
delete[] key;
|
||||
|
||||
if (authResult != SSH_OK) {
|
||||
qDebug() << "failed to export private key";
|
||||
errorCode = ErrorCode::InternalError;
|
||||
}
|
||||
} else {
|
||||
errorCode = ErrorCode::SshPrivateKeyError;
|
||||
}
|
||||
|
||||
ssh_key_free(privateKey);
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
void Client::setPassphraseCallback(const std::function<QString()> &callback)
|
||||
{
|
||||
m_passphraseCallback = callback;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace libssh {
|
|||
Client(QObject *parent = nullptr);
|
||||
~Client();
|
||||
|
||||
ErrorCode connectToHost(const ServerCredentials &credentials, const std::function<QString()> &passphraseCallback);
|
||||
ErrorCode connectToHost(const ServerCredentials &credentials);
|
||||
void disconnectFromHost();
|
||||
ErrorCode executeCommand(const QString &data,
|
||||
const std::function<ErrorCode (const QString &, Client &)> &cbReadStdOut,
|
||||
|
@ -36,6 +36,8 @@ namespace libssh {
|
|||
const std::string& localPath,
|
||||
const std::string& remotePath,
|
||||
const std::string& fileDesc);
|
||||
ErrorCode getDecryptedPrivateKey(const ServerCredentials &credentials, QString &decryptedPrivateKey);
|
||||
void setPassphraseCallback(const std::function<QString()> &callback);
|
||||
private:
|
||||
ErrorCode closeChannel();
|
||||
ErrorCode closeSftpSession();
|
||||
|
|
|
@ -165,6 +165,6 @@
|
|||
<file>ui/qml/Controls/PopupWithQuestion.qml</file>
|
||||
<file>ui/qml/Pages/PageAdvancedServerSettings.qml</file>
|
||||
<file>ui/qml/Controls/PopupWarning.qml</file>
|
||||
<file>ui/qml/Controls/PopupWithInputField.qml</file>
|
||||
<file>ui/qml/Controls/PopupWithTextField.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "configurators/vpn_configurator.h"
|
||||
#include "../uilogic.h"
|
||||
#include "utilities.h"
|
||||
#include "core/servercontroller.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QStandardPaths>
|
||||
|
@ -94,8 +95,7 @@ void StartPageLogic::onPushButtonConnect()
|
|||
set_labelWaitInfoText(tr("Please fill in all fields"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (lineEditIpText().isEmpty() ||
|
||||
lineEditLoginText().isEmpty() ||
|
||||
lineEditPasswordText().isEmpty() ) {
|
||||
|
@ -111,7 +111,7 @@ void StartPageLogic::onPushButtonConnect()
|
|||
serverCredentials.hostName = serverCredentials.hostName.split(":").at(0);
|
||||
}
|
||||
serverCredentials.userName = lineEditLoginText();
|
||||
if (pushButtonConnectKeyChecked()){
|
||||
if (pushButtonConnectKeyChecked()) {
|
||||
QString key = textEditSshKeyText();
|
||||
if (key.startsWith("ssh-rsa")) {
|
||||
emit uiLogic()->showPublicKeyWarning();
|
||||
|
@ -123,28 +123,34 @@ void StartPageLogic::onPushButtonConnect()
|
|||
}
|
||||
|
||||
serverCredentials.password = key;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
serverCredentials.password = lineEditPasswordText();
|
||||
}
|
||||
|
||||
set_pushButtonConnectEnabled(false);
|
||||
set_pushButtonConnectText(tr("Connecting..."));
|
||||
|
||||
ErrorCode e = ErrorCode::NoError;
|
||||
ErrorCode errorCode = ErrorCode::NoError;
|
||||
#ifdef Q_DEBUG
|
||||
//QString output = m_serverController->checkSshConnection(serverCredentials, &e);
|
||||
#else
|
||||
QString output;
|
||||
#endif
|
||||
|
||||
bool ok = true;
|
||||
if (e) {
|
||||
set_labelWaitInfoVisible(true);
|
||||
set_labelWaitInfoText(errorString(e));
|
||||
ok = false;
|
||||
if (pushButtonConnectKeyChecked()) {
|
||||
QString decryptedPrivateKey;
|
||||
errorCode = uiLogic()->m_serverController->getDecryptedPrivateKey(serverCredentials, decryptedPrivateKey);
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
serverCredentials.password = decryptedPrivateKey;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
bool ok = true;
|
||||
if (errorCode) {
|
||||
set_labelWaitInfoVisible(true);
|
||||
set_labelWaitInfoText(errorString(errorCode));
|
||||
ok = false;
|
||||
} else {
|
||||
if (output.contains("Please login as the user")) {
|
||||
output.replace("\n", "");
|
||||
set_labelWaitInfoVisible(true);
|
||||
|
|
|
@ -235,7 +235,7 @@ Window {
|
|||
popupWarning.open()
|
||||
}
|
||||
function onShowPassphraseRequestMessage() {
|
||||
popupWithInputField.open()
|
||||
popupWithTextField.open()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,8 +358,8 @@ Window {
|
|||
PopupWarning {
|
||||
id: popupWarning
|
||||
}
|
||||
PopupWithInputField {
|
||||
id: popupWithInputField
|
||||
PopupWithTextField {
|
||||
id: popupWithTextField
|
||||
placeholderText: "Enter private key passphrase"
|
||||
yesFunc: function() {
|
||||
editingFinished()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue