forked from qt-creator/qt-creator
SSH: Add ssh-askpass implementation
There is no standard implementation for the ssh-askpass tool on any platform, so we currently can't find one on our own. In particular, this means that the RemoteLinux device test will always fail for a newly added device, which is not acceptable. So we just add our own askpass implementation and point the SSH settings to it. Change-Id: I7ca18725e63f591ef9defdf13768a21cc3de4a54 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -40,8 +40,13 @@ namespace Internal {
|
|||||||
SshProcess::SshProcess()
|
SshProcess::SshProcess()
|
||||||
{
|
{
|
||||||
Utils::Environment env = Utils::Environment::systemEnvironment();
|
Utils::Environment env = Utils::Environment::systemEnvironment();
|
||||||
if (SshSettings::askpassFilePath().exists())
|
if (SshSettings::askpassFilePath().exists()) {
|
||||||
env.set("SSH_ASKPASS", SshSettings::askpassFilePath().toUserOutput());
|
env.set("SSH_ASKPASS", SshSettings::askpassFilePath().toUserOutput());
|
||||||
|
|
||||||
|
// OpenSSH only uses the askpass program if DISPLAY is set, regardless of the platform.
|
||||||
|
if (!env.hasKey("DISPLAY"))
|
||||||
|
env.set("DISPLAY", ":0");
|
||||||
|
}
|
||||||
setProcessEnvironment(env.toProcessEnvironment());
|
setProcessEnvironment(env.toProcessEnvironment());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -113,12 +113,23 @@ int SshSettings::connectionSharingTimeout()
|
|||||||
return sshSettings->connectionSharingTimeOutInMinutes;
|
return sshSettings->connectionSharingTimeOutInMinutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FileName filePathValue(const FileName &value, const QString &defaultFileName)
|
static FileName filePathValue(const FileName &value, const QStringList &candidateFileNames)
|
||||||
{
|
{
|
||||||
return !value.isEmpty()
|
if (!value.isEmpty())
|
||||||
? value
|
return value;
|
||||||
: Environment::systemEnvironment().searchInPath(defaultFileName,
|
const QList<FileName> additionalSearchPaths = sshSettings->searchPathRetriever();
|
||||||
sshSettings->searchPathRetriever());
|
for (const QString &candidate : candidateFileNames) {
|
||||||
|
const FileName filePath = Environment::systemEnvironment()
|
||||||
|
.searchInPath(candidate, additionalSearchPaths);
|
||||||
|
if (!filePath.isEmpty())
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
return FileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
static FileName filePathValue(const FileName &value, const QString &candidateFileName)
|
||||||
|
{
|
||||||
|
return filePathValue(value, QStringList(candidateFileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SshSettings::setSshFilePath(const FileName &ssh) { sshSettings->sshFilePath = ssh; }
|
void SshSettings::setSshFilePath(const FileName &ssh) { sshSettings->sshFilePath = ssh; }
|
||||||
@@ -138,7 +149,7 @@ FileName SshSettings::askpassFilePath()
|
|||||||
candidate = sshSettings->askpassFilePath;
|
candidate = sshSettings->askpassFilePath;
|
||||||
if (candidate.isEmpty())
|
if (candidate.isEmpty())
|
||||||
candidate = FileName::fromString(Environment::systemEnvironment().value("SSH_ASKPASS"));
|
candidate = FileName::fromString(Environment::systemEnvironment().value("SSH_ASKPASS"));
|
||||||
return filePathValue(candidate, "ssh-askpass");
|
return filePathValue(candidate, QStringList{"qtc-askpass", "ssh-askpass"});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SshSettings::setKeygenFilePath(const FileName &keygen)
|
void SshSettings::setKeygenFilePath(const FileName &keygen)
|
||||||
|
|||||||
@@ -1723,8 +1723,10 @@ void ProjectExplorerPlugin::extensionsInitialized()
|
|||||||
DeviceManager::instance()->addDevice(IDevice::Ptr(new DesktopDevice));
|
DeviceManager::instance()->addDevice(IDevice::Ptr(new DesktopDevice));
|
||||||
|
|
||||||
QSsh::SshSettings::loadSettings(Core::ICore::settings());
|
QSsh::SshSettings::loadSettings(Core::ICore::settings());
|
||||||
if (Utils::HostOsInfo::isWindowsHost()) {
|
const auto searchPathRetriever = [] {
|
||||||
const auto searchPathRetriever = [] {
|
Utils::FileNameList searchPaths;
|
||||||
|
searchPaths << Utils::FileName::fromString(Core::ICore::libexecPath());
|
||||||
|
if (Utils::HostOsInfo::isWindowsHost()) {
|
||||||
const QString gitBinary = Core::ICore::settings()->value("Git/BinaryPath", "git")
|
const QString gitBinary = Core::ICore::settings()->value("Git/BinaryPath", "git")
|
||||||
.toString();
|
.toString();
|
||||||
const QStringList rawGitSearchPaths = Core::ICore::settings()->value("Git/Path")
|
const QStringList rawGitSearchPaths = Core::ICore::settings()->value("Git/Path")
|
||||||
@@ -1733,15 +1735,14 @@ void ProjectExplorerPlugin::extensionsInitialized()
|
|||||||
[](const QString &rawPath) { return Utils::FileName::fromString(rawPath); });
|
[](const QString &rawPath) { return Utils::FileName::fromString(rawPath); });
|
||||||
const Utils::FileName fullGitPath = Utils::Environment::systemEnvironment()
|
const Utils::FileName fullGitPath = Utils::Environment::systemEnvironment()
|
||||||
.searchInPath(gitBinary, gitSearchPaths);
|
.searchInPath(gitBinary, gitSearchPaths);
|
||||||
if (fullGitPath.isEmpty())
|
if (!fullGitPath.isEmpty()) {
|
||||||
return Utils::FileNameList();
|
searchPaths << fullGitPath.parentDir()
|
||||||
return Utils::FileNameList{
|
<< fullGitPath.parentDir().parentDir() + "/usr/bin";
|
||||||
fullGitPath.parentDir(),
|
}
|
||||||
fullGitPath.parentDir().parentDir() + "/usr/bin"
|
}
|
||||||
};
|
return searchPaths;
|
||||||
};
|
};
|
||||||
QSsh::SshSettings::setExtraSearchPathRetriever(searchPathRetriever);
|
QSsh::SshSettings::setExtraSearchPathRetriever(searchPathRetriever);
|
||||||
}
|
|
||||||
|
|
||||||
// delay restoring kits until UI is shown for improved perceived startup performance
|
// delay restoring kits until UI is shown for improved perceived startup performance
|
||||||
QTimer::singleShot(0, this, &ProjectExplorerPlugin::restoreKits);
|
QTimer::singleShot(0, this, &ProjectExplorerPlugin::restoreKits);
|
||||||
|
|||||||
47
src/tools/qtc-askpass/qtc-askpass-main.cpp
Normal file
47
src/tools/qtc-askpass/qtc-askpass-main.cpp
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2018 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
QTimer::singleShot(0, [] {
|
||||||
|
QInputDialog dlg;
|
||||||
|
const QStringList appArgs = qApp->arguments();
|
||||||
|
QString labelText = QCoreApplication::translate("qtc-askpass",
|
||||||
|
"Password required for SSH login.");
|
||||||
|
if (appArgs.count() > 1)
|
||||||
|
labelText.append('\n').append(appArgs.at(1));
|
||||||
|
dlg.setLabelText(labelText);
|
||||||
|
dlg.setTextEchoMode(QLineEdit::Password);
|
||||||
|
if (dlg.exec() == QDialog::Accepted)
|
||||||
|
std::cout << qPrintable(dlg.textValue()) << std::endl;
|
||||||
|
});
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
5
src/tools/qtc-askpass/qtc-askpass.pro
Normal file
5
src/tools/qtc-askpass/qtc-askpass.pro
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
include(../../qtcreatortool.pri)
|
||||||
|
|
||||||
|
TARGET = qtc-askpass
|
||||||
|
|
||||||
|
SOURCES = qtc-askpass-main.cpp
|
||||||
9
src/tools/qtc-askpass/qtc-askpass.qbs
Normal file
9
src/tools/qtc-askpass/qtc-askpass.qbs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import qbs
|
||||||
|
|
||||||
|
QtcTool {
|
||||||
|
name: "qtc-askpass"
|
||||||
|
Depends { name: "Qt.widgets" }
|
||||||
|
files: [
|
||||||
|
"qtc-askpass-main.cpp",
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -6,7 +6,8 @@ SUBDIRS = qtpromaker \
|
|||||||
../plugins/cpaster/frontend \
|
../plugins/cpaster/frontend \
|
||||||
valgrindfake \
|
valgrindfake \
|
||||||
3rdparty \
|
3rdparty \
|
||||||
buildoutputparser
|
buildoutputparser \
|
||||||
|
qtc-askpass
|
||||||
|
|
||||||
isEmpty(QTC_SKIP_SDKTOOL): SUBDIRS += sdktool
|
isEmpty(QTC_SKIP_SDKTOOL): SUBDIRS += sdktool
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ Project {
|
|||||||
"qml2puppet/qml2puppet.qbs",
|
"qml2puppet/qml2puppet.qbs",
|
||||||
"qtcdebugger/qtcdebugger.qbs",
|
"qtcdebugger/qtcdebugger.qbs",
|
||||||
"qtcreatorcrashhandler/qtcreatorcrashhandler.qbs",
|
"qtcreatorcrashhandler/qtcreatorcrashhandler.qbs",
|
||||||
|
"qtc-askpass/qtc-askpass.qbs",
|
||||||
"qtpromaker/qtpromaker.qbs",
|
"qtpromaker/qtpromaker.qbs",
|
||||||
"sdktool/sdktool.qbs",
|
"sdktool/sdktool.qbs",
|
||||||
"valgrindfake/valgrindfake.qbs",
|
"valgrindfake/valgrindfake.qbs",
|
||||||
|
|||||||
Reference in New Issue
Block a user