Avoid piping LUKS passphrase.

Also remove piping support from ExternalCommand.
It's unlikely that it will be useful enough. There were no more users of this
after luks open was migrated to QProcess::write.
This commit is contained in:
Andrius Štikonas 2016-05-09 00:41:44 +01:00
parent bb2de6cd56
commit 785aa7edf4
3 changed files with 54 additions and 126 deletions

View File

@ -113,31 +113,24 @@ bool luks::create(Report& report, const QString& deviceNode) const
Q_ASSERT(m_innerFs);
Q_ASSERT(!m_passphrase.isEmpty());
std::vector<QString> commands;
commands.push_back(QStringLiteral("echo"));
commands.push_back(QStringLiteral("cryptsetup"));
std::vector<QStringList> args;
args.push_back({ m_passphrase });
args.push_back({ QStringLiteral("-s"),
QStringLiteral("512"),
QStringLiteral("luksFormat"),
deviceNode });
ExternalCommand createCmd(commands, args);
if (!(createCmd.run(-1) && createCmd.exitCode() == 0))
ExternalCommand createCmd(report, QStringLiteral("cryptsetup"),
{ QStringLiteral("-s"),
QStringLiteral("512"),
QStringLiteral("luksFormat"),
deviceNode });
if (!( createCmd.start(-1) &&
createCmd.write(m_passphrase.toLatin1() + '\n' + m_passphrase.toLatin1() + '\n') == 2*(m_passphrase.toLatin1().length() + 1) &&
createCmd.waitFor() && createCmd.exitCode() == 0))
{
return false;
}
commands.clear();
commands.push_back(QStringLiteral("echo"));
commands.push_back(QStringLiteral("cryptsetup"));
args.clear();
args.push_back({ m_passphrase });
args.push_back({ QStringLiteral("open"),
deviceNode,
suggestedMapperName(deviceNode) });
ExternalCommand openCmd(report, QStringLiteral("cryptsetup"),
{ QStringLiteral("open"),
deviceNode,
suggestedMapperName(deviceNode) });
ExternalCommand openCmd(commands, args);
if (!(openCmd.run(-1) && openCmd.exitCode() == 0))
if (!( openCmd.start(-1) && openCmd.write(m_passphrase.toLatin1() + '\n') == m_passphrase.toLatin1().length() + 1 && openCmd.waitFor()))
return false;
QString mapperNode = mapperName(deviceNode);
@ -257,18 +250,17 @@ bool luks::cryptOpen(QWidget* parent, const QString& deviceNode)
return false;
QString passphrase = dlg.password();
std::vector<QString> commands;
commands.push_back(QStringLiteral("echo"));
commands.push_back(QStringLiteral("cryptsetup"));
std::vector<QStringList> args;
args.push_back({ passphrase });
args.push_back({ QStringLiteral("open"),
deviceNode,
suggestedMapperName(deviceNode) });
ExternalCommand openCmd(QStringLiteral("cryptsetup"),
{ QStringLiteral("open"),
deviceNode,
suggestedMapperName(deviceNode) });
ExternalCommand cmd(commands, args);
if (!(cmd.run(-1) && cmd.exitCode() == 0))
if (!( openCmd.start(-1) &&
openCmd.write(passphrase.toLatin1() + '\n') == passphrase.toLatin1().length() + 1 &&
openCmd.waitFor() && openCmd.exitCode() == 0) )
{
return false;
}
if (m_innerFs)
{

View File

@ -32,12 +32,13 @@
@param args the arguments to pass to the command
*/
ExternalCommand::ExternalCommand(const QString& cmd, const QStringList& args) :
QProcess(),
m_Report(nullptr),
m_Command(cmd),
m_Args(args),
m_ExitCode(-1),
m_Output()
{
m_Command.push_back(cmd);
m_Args.push_back(args);
setup();
}
@ -47,35 +48,7 @@ ExternalCommand::ExternalCommand(const QString& cmd, const QStringList& args) :
@param args the arguments to pass to the command
*/
ExternalCommand::ExternalCommand(Report& report, const QString& cmd, const QStringList& args) :
m_Report(report.newChild()),
m_ExitCode(-1),
m_Output()
{
m_Command.push_back(cmd);
m_Args.push_back(args);
setup();
}
/** Creates a new ExternalCommand instance without Report.
@param cmd the vector of the piped commands to run
@param args the vector of the arguments to pass to the commands
*/
ExternalCommand::ExternalCommand(const std::vector<QString> cmd, const std::vector<QStringList> args) :
m_Report(nullptr),
m_Command(cmd),
m_Args(args),
m_ExitCode(-1),
m_Output()
{
setup();
}
/** Creates a new ExternalCommand instance with Report.
@param report the Report to write output to.
@param cmd the vector of the piped commands to run
@param args the vector of the arguments to pass to the commands
*/
ExternalCommand::ExternalCommand(Report& report, const std::vector<QString> cmd, const std::vector<QStringList> args) :
QProcess(),
m_Report(report.newChild()),
m_Command(cmd),
m_Args(args),
@ -85,72 +58,52 @@ ExternalCommand::ExternalCommand(Report& report, const std::vector<QString> cmd,
setup();
}
ExternalCommand::~ExternalCommand()
{
delete[] processes;
}
void ExternalCommand::setup()
{
setEnvironment(QStringList() << QStringLiteral("LC_ALL=C") << QStringLiteral("PATH=") + QString::fromUtf8(getenv("PATH")));
setProcessChannelMode(MergedChannels);
processes = new QProcess[command().size()];
connect(&processes[command().size() - 1], SIGNAL(readyReadStandardOutput()), SLOT(onReadOutput()));
connect(&processes[command().size() - 1], SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(onFinished(int)));
for (unsigned int i = 0; i < command().size() - 1; i++) {
processes[i].setStandardOutputProcess(&processes[i + 1]);
}
connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(onFinished(int)));
connect(this, SIGNAL(readyReadStandardOutput()), SLOT(onReadOutput()));
}
/** Starts the external commands.
/** Starts the external command.
@param timeout timeout to wait for the process to start
@return true on success
*/
bool ExternalCommand::start(int timeout)
{
for (unsigned int i = 0; i < command().size(); i++)
processes[i].start(command()[i], args()[i]);
QProcess::start(command(), args());
if (report()) {
QString s;
for (unsigned int i = 0; i < command().size(); i++) {
s += command()[i] + QStringLiteral(" ") + args()[i].join(QStringLiteral(" "));
if (i < command().size() - 1)
s += QStringLiteral(" | ");
}
report()->setCommand(i18nc("@info/plain", "Command: %1", s));
report()->setCommand(i18nc("@info/plain", "Command: %1 %2", command(), args().join(QStringLiteral(" "))));
}
for (unsigned int i = 0; i < command().size(); i++) {
if (!processes[i].waitForStarted(timeout)) {
if (report())
report()->line() << i18nc("@info/plain", "(Command timeout while starting \"%1\")", command()[i] + QStringLiteral(" ") + args()[i].join(QStringLiteral(" ")));
return false;
}
if (!waitForStarted(timeout))
{
if (report())
report()->line() << i18nc("@info/plain", "(Command timeout while starting)");
return false;
}
return true;
}
/** Waits for the external commands to finish.
/** Waits for the external command to finish.
@param timeout timeout to wait until the process finishes.
@return true on success
*/
bool ExternalCommand::waitFor(int timeout)
{
for (unsigned int i = 0; i < command().size(); i++) {
processes[i].closeWriteChannel();
closeWriteChannel();
if (!processes[i].waitForFinished(timeout)) {
if (report())
report()->line() << i18nc("@info/plain", "(Command timeout while running \"%1\")", command()[i] + QStringLiteral(" ") + args()[i].join(QStringLiteral(" ")));
return false;
}
onReadOutput();
if (!waitForFinished(timeout)) {
if (report())
report()->line() << i18nc("@info/plain", "(Command timeout while running)");
return false;
}
onReadOutput();
return true;
}
@ -165,7 +118,7 @@ bool ExternalCommand::run(int timeout)
void ExternalCommand::onReadOutput()
{
const QString s = QString::fromUtf8(processes[command().size() - 1].readAllStandardOutput());
const QString s = QString::fromUtf8(readAllStandardOutput());
m_Output += s;

View File

@ -45,30 +45,14 @@ class LIBKPMCORE_EXPORT ExternalCommand : public QProcess
public:
explicit ExternalCommand(const QString& cmd = QString(), const QStringList& args = QStringList());
explicit ExternalCommand(Report& report, const QString& cmd = QString(), const QStringList& args = QStringList());
explicit ExternalCommand(const std::vector<QString> cmd, const std::vector<QStringList> args);
explicit ExternalCommand(Report& report, const std::vector<QString> cmd, const std::vector<QStringList> args);
~ExternalCommand();
public:
void setCommand(const std::vector<QString> cmd) {
m_Command = cmd; /**< @param cmd the command to run */
}
const std::vector<QString> command() const {
return m_Command; /**< @return the command to run */
}
void setCommand(const QString& cmd) { m_Command = cmd; } /**< @param cmd the command to run */
const QString& command() const { return m_Command; } /**< @return the command to run */
/** @param s the argument to add
@param i the command to which the argument is added
*/
void addArg(const QString& s, const int i = 0) {
m_Args[i] << s;
}
const std::vector<QStringList> args() const {
return m_Args; /**< @return the arguments */
}
void setArgs(const std::vector<QStringList> args) {
m_Args = args; /**< @param args the new arguments */
}
void addArg(const QString& s) { m_Args << s; } /**< @param s the argument to add */
const QStringList& args() const { return m_Args; } /**< @return the arguments */
void setArgs(const QStringList& args) { m_Args = args; } /**< @param args the new arguments */
bool start(int timeout = 30000);
bool waitFor(int timeout = 30000);
@ -97,10 +81,9 @@ protected Q_SLOTS:
void onReadOutput();
private:
QProcess *processes;
Report *m_Report;
std::vector<QString> m_Command;
std::vector<QStringList> m_Args;
QString m_Command;
QStringList m_Args;
int m_ExitCode;
QString m_Output;
};