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
|
bool fat12::updateUUID(Report& report, const QString& deviceNode) const
|
||||||
{
|
{
|
||||||
qint64 t = time(nullptr);
|
long int t = time(nullptr);
|
||||||
|
|
||||||
char uuid[4];
|
char uuid[4];
|
||||||
for (auto &u : uuid) {
|
for (auto &u : uuid) {
|
||||||
|
@ -165,9 +165,7 @@ bool fat12::updateUUID(Report& report, const QString& deviceNode) const
|
||||||
t >>= 8;
|
t >>= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=39") });
|
ExternalCommand cmd;
|
||||||
|
return cmd.writeData(report, QByteArray(uuid, sizeof(uuid)), deviceNode, 39);
|
||||||
cmd.write(QByteArray(uuid, sizeof(uuid)));
|
|
||||||
return cmd.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
* You should have received a copy of the GNU General Public License *
|
* You should have received a copy of the GNU General Public License *
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
#include "fs/fat32.h"
|
#include "fs/fat32.h"
|
||||||
|
|
||||||
#include "util/externalcommand.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
|
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];
|
char uuid[4];
|
||||||
for (auto &u : uuid) {
|
for (auto &u : uuid) {
|
||||||
|
@ -56,10 +58,7 @@ bool fat32::updateUUID(Report& report, const QString& deviceNode) const
|
||||||
t >>= 8;
|
t >>= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK: replace this hack with fatlabel "-i" (dosfstools 4.2)
|
ExternalCommand cmd;
|
||||||
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode, QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=67") });
|
return cmd.writeData(report, QByteArray(uuid, sizeof(uuid)), deviceNode, 67);
|
||||||
|
|
||||||
cmd.write(QByteArray(uuid, sizeof(uuid)));
|
|
||||||
return cmd.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QUuid>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
@ -188,10 +187,8 @@ bool ntfs::updateBootSector(Report& report, const QString& deviceNode) const
|
||||||
std::swap(s[1], s[2]);
|
std::swap(s[1], s[2]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ExternalCommand cmd(report, QStringLiteral("dd"), { QStringLiteral("of=") + deviceNode , QStringLiteral("bs=1"), QStringLiteral("count=4"), QStringLiteral("seek=28") });
|
ExternalCommand cmd;
|
||||||
|
if (!cmd.writeData(report, QByteArray(s, sizeof(s)), deviceNode, 28)) {
|
||||||
cmd.write(QByteArray(s, sizeof(s)));
|
|
||||||
if (!cmd.start()) {
|
|
||||||
Log() << xi18nc("@info:progress", "Could not write new start sector to partition <filename>%1</filename> when trying to update the NTFS boot sector.", deviceNode);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,6 +241,55 @@ bool ExternalCommand::copyBlocks(CopySource& source, CopyTarget& target)
|
||||||
return rval;
|
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)
|
bool ExternalCommand::write(const QByteArray& input)
|
||||||
{
|
{
|
||||||
|
|
|
@ -69,6 +69,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool copyBlocks(CopySource& source, CopyTarget& target);
|
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 */
|
/**< @param cmd the command to run */
|
||||||
void setCommand(const QString& cmd);
|
void setCommand(const QString& cmd);
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
QString allowedCommands[] = {
|
QString allowedCommands[] = {
|
||||||
// TODO try to remove these later
|
// TODO try to remove these later
|
||||||
QStringLiteral("mv"),
|
QStringLiteral("mv"),
|
||||||
QStringLiteral("dd"),
|
|
||||||
|
|
||||||
// TODO no root needed
|
// TODO no root needed
|
||||||
QStringLiteral("lsblk"),
|
QStringLiteral("lsblk"),
|
||||||
|
|
|
@ -152,6 +152,7 @@ bool ExternalCommandHelper::writeData(const QString &targetDevice, const QByteAr
|
||||||
return true;
|
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 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;
|
QVariantMap reply;
|
||||||
|
@ -213,7 +214,7 @@ QVariantMap ExternalCommandHelper::copyblocks(const QByteArray& signature, const
|
||||||
|
|
||||||
bool rval = true;
|
bool rval = true;
|
||||||
|
|
||||||
while (blocksCopied < blocksToCopy) {
|
while (blocksCopied < blocksToCopy && !targetDevice.isEmpty()) {
|
||||||
if (!(rval = readData(sourceDevice, buffer, readOffset + blockSize * blocksCopied * copyDirection, blockSize)))
|
if (!(rval = readData(sourceDevice, buffer, readOffset + blockSize * blocksCopied * copyDirection, blockSize)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -265,6 +266,33 @@ QVariantMap ExternalCommandHelper::copyblocks(const QByteArray& signature, const
|
||||||
return reply;
|
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)
|
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"));
|
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
|
||||||
|
|
|
@ -50,6 +50,7 @@ public Q_SLOTS:
|
||||||
Q_SCRIPTABLE quint64 getNonce();
|
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 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 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);
|
Q_SCRIPTABLE void exit(const QByteArray& signature, const quint64 nonce);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue