parent
0e4fca8de6
commit
09e4d47e07
|
@ -157,7 +157,7 @@ bool fat12::create(Report& report, const QString& deviceNode)
|
|||
|
||||
bool fat12::updateUUID(Report& report, const QString& deviceNode) const
|
||||
{
|
||||
qint64 t = time(nullptr);
|
||||
long int t = time(nullptr);
|
||||
|
||||
char uuid[4];
|
||||
for (auto &u : uuid) {
|
||||
|
@ -165,9 +165,7 @@ bool fat12::updateUUID(Report& report, const QString& deviceNode) const
|
|||
t >>= 8;
|
||||
}
|
||||
|
||||
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=39") });
|
||||
|
||||
cmd.write(QByteArray(uuid, sizeof(uuid)));
|
||||
return cmd.start();
|
||||
ExternalCommand cmd;
|
||||
return cmd.writeData(report, QByteArray(uuid, sizeof(uuid)), deviceNode, 39);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||
*************************************************************************/
|
||||
|
||||
#include "fs/fat32.h"
|
||||
|
||||
#include "util/externalcommand.h"
|
||||
|
@ -48,7 +49,8 @@ bool fat32::create(Report& report, const QString& deviceNode)
|
|||
|
||||
bool fat32::updateUUID(Report& report, const QString& deviceNode) const
|
||||
{
|
||||
qint64 t = time(nullptr);
|
||||
// HACK: replace this hack with fatlabel "-i" (dosfstools 4.2)
|
||||
long int t = time(nullptr);
|
||||
|
||||
char uuid[4];
|
||||
for (auto &u : uuid) {
|
||||
|
@ -56,10 +58,7 @@ bool fat32::updateUUID(Report& report, const QString& deviceNode) const
|
|||
t >>= 8;
|
||||
}
|
||||
|
||||
// HACK: replace this hack with fatlabel "-i" (dosfstools 4.2)
|
||||
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode, QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=67") });
|
||||
|
||||
cmd.write(QByteArray(uuid, sizeof(uuid)));
|
||||
return cmd.start();
|
||||
ExternalCommand cmd;
|
||||
return cmd.writeData(report, QByteArray(uuid, sizeof(uuid)), deviceNode, 67);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QFile>
|
||||
#include <QUuid>
|
||||
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
|
@ -188,10 +187,8 @@ bool ntfs::updateBootSector(Report& report, const QString& deviceNode) const
|
|||
std::swap(s[1], s[2]);
|
||||
#endif
|
||||
|
||||
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=28") });
|
||||
|
||||
cmd.write(QByteArray(s, sizeof(s)));
|
||||
if (!cmd.start()) {
|
||||
ExternalCommand cmd;
|
||||
if (!cmd.writeData(report, QByteArray(s, sizeof(s)), deviceNode, 28)) {
|
||||
Log() << xi18nc("@info:progress", "Could not write new start sector to partition <filename>%1</filename> when trying to update the NTFS boot sector.", deviceNode);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -241,6 +241,55 @@ bool ExternalCommand::copyBlocks(CopySource& source, CopyTarget& target)
|
|||
return rval;
|
||||
}
|
||||
|
||||
bool ExternalCommand::writeData(Report& commandReport, const QByteArray& buffer, const QString& deviceNode, const quint64 firstByte)
|
||||
{
|
||||
d->m_Report = commandReport.newChild();
|
||||
if (report())
|
||||
report()->setCommand(xi18nc("@info:status", "Command: %1 %2", command(), args().join(QStringLiteral(" "))));
|
||||
|
||||
bool rval = true;
|
||||
|
||||
if (!QDBusConnection::systemBus().isConnected()) {
|
||||
qWarning() << "Could not connect to DBus system bus";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto *interface = new org::kde::kpmcore::externalcommand(QStringLiteral("org.kde.kpmcore.externalcommand"),
|
||||
QStringLiteral("/Helper"), QDBusConnection::systemBus(), this);
|
||||
interface->setTimeout(10 * 24 * 3600 * 1000); // 10 days
|
||||
QByteArray request;
|
||||
|
||||
const quint64 nonce = interface->getNonce();
|
||||
request.setNum(nonce);
|
||||
request.append(buffer);
|
||||
request.append(deviceNode.toUtf8());
|
||||
request.append(QByteArray::number(firstByte));
|
||||
|
||||
QByteArray hash = QCryptographicHash::hash(request, QCryptographicHash::Sha512);
|
||||
|
||||
QDBusPendingCall pcall = interface->writeData(privateKey->signMessage(hash, QCA::EMSA3_Raw), nonce,
|
||||
buffer, deviceNode, firstByte);
|
||||
|
||||
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
|
||||
QEventLoop loop;
|
||||
|
||||
auto exitLoop = [&] (QDBusPendingCallWatcher *watcher) {
|
||||
loop.exit();
|
||||
if (watcher->isError())
|
||||
qWarning() << watcher->error();
|
||||
else {
|
||||
QDBusPendingReply<bool> reply = *watcher;
|
||||
rval = reply.argumentAt<0>();
|
||||
}
|
||||
setExitCode(!rval);
|
||||
};
|
||||
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, exitLoop);
|
||||
loop.exec();
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
||||
bool ExternalCommand::write(const QByteArray& input)
|
||||
{
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
|
||||
public:
|
||||
bool copyBlocks(CopySource& source, CopyTarget& target);
|
||||
bool writeData(Report& report, const QByteArray& buffer, const QString& deviceNode, const quint64 firstByte); // same as copyBlocks but from QByteArray
|
||||
|
||||
/**< @param cmd the command to run */
|
||||
void setCommand(const QString& cmd);
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
QString allowedCommands[] = {
|
||||
// TODO try to remove these later
|
||||
QStringLiteral("mv"),
|
||||
QStringLiteral("dd"),
|
||||
|
||||
// TODO no root needed
|
||||
QStringLiteral("lsblk"),
|
||||
|
|
|
@ -152,6 +152,7 @@ bool ExternalCommandHelper::writeData(const QString &targetDevice, const QByteAr
|
|||
return true;
|
||||
}
|
||||
|
||||
// If targetDevice is empty then return QByteArray with data that was read from disk.
|
||||
QVariantMap ExternalCommandHelper::copyblocks(const QByteArray& signature, const quint64 nonce, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize)
|
||||
{
|
||||
QVariantMap reply;
|
||||
|
@ -213,7 +214,7 @@ QVariantMap ExternalCommandHelper::copyblocks(const QByteArray& signature, const
|
|||
|
||||
bool rval = true;
|
||||
|
||||
while (blocksCopied < blocksToCopy) {
|
||||
while (blocksCopied < blocksToCopy && !targetDevice.isEmpty()) {
|
||||
if (!(rval = readData(sourceDevice, buffer, readOffset + blockSize * blocksCopied * copyDirection, blockSize)))
|
||||
break;
|
||||
|
||||
|
@ -265,6 +266,33 @@ QVariantMap ExternalCommandHelper::copyblocks(const QByteArray& signature, const
|
|||
return reply;
|
||||
}
|
||||
|
||||
bool ExternalCommandHelper::writeData(const QByteArray& signature, const quint64 nonce, const QByteArray buffer, const QString& targetDevice, const qint64 targetFirstByte)
|
||||
{
|
||||
if (m_Nonces.find(nonce) != m_Nonces.end())
|
||||
m_Nonces.erase( nonce );
|
||||
else
|
||||
return false;
|
||||
|
||||
QByteArray request;
|
||||
request.setNum(nonce);
|
||||
request.append(buffer);
|
||||
request.append(targetDevice.toUtf8());
|
||||
request.append(QByteArray::number(targetFirstByte));
|
||||
|
||||
// Do not allow using this helper for writing to arbitrary location
|
||||
if ( targetDevice.left(5) != QStringLiteral("/dev/") && !targetDevice.contains(QStringLiteral("/etc/fstab")))
|
||||
return false;
|
||||
|
||||
QByteArray hash = QCryptographicHash::hash(request, QCryptographicHash::Sha512);
|
||||
if (!m_publicKey.verifyMessage(hash, signature, QCA::EMSA3_Raw)) {
|
||||
qCritical() << xi18n("Invalid cryptographic signature");
|
||||
return false;
|
||||
}
|
||||
|
||||
return writeData(targetDevice, buffer, targetFirstByte);
|
||||
}
|
||||
|
||||
|
||||
QVariantMap ExternalCommandHelper::start(const QByteArray& signature, const quint64 nonce, const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode)
|
||||
{
|
||||
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
|
||||
|
|
|
@ -50,6 +50,7 @@ public Q_SLOTS:
|
|||
Q_SCRIPTABLE quint64 getNonce();
|
||||
Q_SCRIPTABLE QVariantMap start(const QByteArray& signature, const quint64 nonce, const QString& command, const QStringList& arguments, const QByteArray& input, const int processChannelMode);
|
||||
Q_SCRIPTABLE QVariantMap copyblocks(const QByteArray& signature, const quint64 nonce, const QString& sourceDevice, const qint64 sourceFirstByte, const qint64 sourceLength, const QString& targetDevice, const qint64 targetFirstByte, const qint64 blockSize);
|
||||
Q_SCRIPTABLE bool writeData(const QByteArray& signature, const quint64 nonce, const QByteArray buffer, const QString& targetDevice, const qint64 targetFirstByte);
|
||||
Q_SCRIPTABLE void exit(const QByteArray& signature, const quint64 nonce);
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue