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()
|
||||
{
|
||||
Utils::Environment env = Utils::Environment::systemEnvironment();
|
||||
if (SshSettings::askpassFilePath().exists())
|
||||
if (SshSettings::askpassFilePath().exists()) {
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
@@ -113,12 +113,23 @@ int SshSettings::connectionSharingTimeout()
|
||||
return sshSettings->connectionSharingTimeOutInMinutes;
|
||||
}
|
||||
|
||||
static FileName filePathValue(const FileName &value, const QString &defaultFileName)
|
||||
static FileName filePathValue(const FileName &value, const QStringList &candidateFileNames)
|
||||
{
|
||||
return !value.isEmpty()
|
||||
? value
|
||||
: Environment::systemEnvironment().searchInPath(defaultFileName,
|
||||
sshSettings->searchPathRetriever());
|
||||
if (!value.isEmpty())
|
||||
return value;
|
||||
const QList<FileName> additionalSearchPaths = 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; }
|
||||
@@ -138,7 +149,7 @@ FileName SshSettings::askpassFilePath()
|
||||
candidate = sshSettings->askpassFilePath;
|
||||
if (candidate.isEmpty())
|
||||
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)
|
||||
|
||||
@@ -1723,8 +1723,10 @@ void ProjectExplorerPlugin::extensionsInitialized()
|
||||
DeviceManager::instance()->addDevice(IDevice::Ptr(new DesktopDevice));
|
||||
|
||||
QSsh::SshSettings::loadSettings(Core::ICore::settings());
|
||||
if (Utils::HostOsInfo::isWindowsHost()) {
|
||||
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")
|
||||
.toString();
|
||||
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 Utils::FileName fullGitPath = Utils::Environment::systemEnvironment()
|
||||
.searchInPath(gitBinary, gitSearchPaths);
|
||||
if (fullGitPath.isEmpty())
|
||||
return Utils::FileNameList();
|
||||
return Utils::FileNameList{
|
||||
fullGitPath.parentDir(),
|
||||
fullGitPath.parentDir().parentDir() + "/usr/bin"
|
||||
};
|
||||
if (!fullGitPath.isEmpty()) {
|
||||
searchPaths << fullGitPath.parentDir()
|
||||
<< fullGitPath.parentDir().parentDir() + "/usr/bin";
|
||||
}
|
||||
}
|
||||
return searchPaths;
|
||||
};
|
||||
QSsh::SshSettings::setExtraSearchPathRetriever(searchPathRetriever);
|
||||
}
|
||||
|
||||
// delay restoring kits until UI is shown for improved perceived startup performance
|
||||
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 \
|
||||
valgrindfake \
|
||||
3rdparty \
|
||||
buildoutputparser
|
||||
buildoutputparser \
|
||||
qtc-askpass
|
||||
|
||||
isEmpty(QTC_SKIP_SDKTOOL): SUBDIRS += sdktool
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ Project {
|
||||
"qml2puppet/qml2puppet.qbs",
|
||||
"qtcdebugger/qtcdebugger.qbs",
|
||||
"qtcreatorcrashhandler/qtcreatorcrashhandler.qbs",
|
||||
"qtc-askpass/qtc-askpass.qbs",
|
||||
"qtpromaker/qtpromaker.qbs",
|
||||
"sdktool/sdktool.qbs",
|
||||
"valgrindfake/valgrindfake.qbs",
|
||||
|
||||
Reference in New Issue
Block a user