mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-25 10:46:15 +03:00
Add support for Mark-of-the-Web
https://redcanary.com/threat-detection-report/techniques/mark-of-the-web-bypass/ https://mikehadlow.blogspot.com/2011/07/detecting-and-changing-files-internet.html https://textslashplain.com/2016/04/04/downloads-and-the-mark-of-the-web/ Closes #19648. PR #19675.
This commit is contained in:
parent
c051ee9409
commit
34f7b75f12
4 changed files with 56 additions and 2 deletions
|
@ -43,6 +43,7 @@
|
||||||
#include <libtorrent/info_hash.hpp>
|
#include <libtorrent/info_hash.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <QtSystemDetection>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
@ -67,6 +68,10 @@
|
||||||
#include "peerinfo.h"
|
#include "peerinfo.h"
|
||||||
#include "sessionimpl.h"
|
#include "sessionimpl.h"
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include "base/utils/misc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace BitTorrent;
|
using namespace BitTorrent;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -2193,10 +2198,20 @@ void TorrentImpl::handleFileCompletedAlert(const lt::file_completed_alert *p)
|
||||||
|
|
||||||
m_completedFiles.setBit(fileIndex);
|
m_completedFiles.setBit(fileIndex);
|
||||||
|
|
||||||
|
const Path actualPath = actualFilePath(fileIndex);
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
// only apply Mark-of-the-Web to new download files
|
||||||
|
if (isDownloading())
|
||||||
|
{
|
||||||
|
const Path fullpath = actualStorageLocation() / actualPath;
|
||||||
|
Utils::Misc::applyMarkOfTheWeb(fullpath);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (m_session->isAppendExtensionEnabled())
|
if (m_session->isAppendExtensionEnabled())
|
||||||
{
|
{
|
||||||
const Path path = filePath(fileIndex);
|
const Path path = filePath(fileIndex);
|
||||||
const Path actualPath = actualFilePath(fileIndex);
|
|
||||||
if (actualPath != path)
|
if (actualPath != path)
|
||||||
{
|
{
|
||||||
qDebug("Renaming %s to %s", qUtf8Printable(actualPath.toString()), qUtf8Printable(path.toString()));
|
qDebug("Renaming %s to %s", qUtf8Printable(actualPath.toString()), qUtf8Printable(path.toString()));
|
||||||
|
@ -2331,7 +2346,7 @@ void TorrentImpl::adjustStorageLocation()
|
||||||
moveStorage(targetPath, MoveStorageContext::AdjustCurrentLocation);
|
moveStorage(targetPath, MoveStorageContext::AdjustCurrentLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TorrentImpl::doRenameFile(int index, const Path &path)
|
void TorrentImpl::doRenameFile(const int index, const Path &path)
|
||||||
{
|
{
|
||||||
const QVector<lt::file_index_t> nativeIndexes = m_torrentInfo.nativeIndexes();
|
const QVector<lt::file_index_t> nativeIndexes = m_torrentInfo.nativeIndexes();
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include "downloadhandlerimpl.h"
|
#include "downloadhandlerimpl.h"
|
||||||
|
|
||||||
|
#include <QtSystemDetection>
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
|
||||||
|
@ -146,19 +147,35 @@ void Net::DownloadHandlerImpl::processFinishedDownload()
|
||||||
{
|
{
|
||||||
const nonstd::expected<Path, QString> result = saveToTempFile(m_result.data);
|
const nonstd::expected<Path, QString> result = saveToTempFile(m_result.data);
|
||||||
if (result)
|
if (result)
|
||||||
|
{
|
||||||
m_result.filePath = result.value();
|
m_result.filePath = result.value();
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
Utils::Misc::applyMarkOfTheWeb(m_result.filePath, m_result.url);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
setError(tr("I/O Error: %1").arg(result.error()));
|
setError(tr("I/O Error: %1").arg(result.error()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const nonstd::expected<void, QString> result = Utils::IO::saveToFile(destinationPath, m_result.data);
|
const nonstd::expected<void, QString> result = Utils::IO::saveToFile(destinationPath, m_result.data);
|
||||||
if (result)
|
if (result)
|
||||||
|
{
|
||||||
m_result.filePath = destinationPath;
|
m_result.filePath = destinationPath;
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
Utils::Misc::applyMarkOfTheWeb(m_result.filePath, m_result.url);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
setError(tr("I/O Error: %1").arg(result.error()));
|
setError(tr("I/O Error: %1").arg(result.error()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -602,6 +602,27 @@ QString Utils::Misc::zlibVersionString()
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
bool Utils::Misc::applyMarkOfTheWeb(const Path &file, const QString &url)
|
||||||
|
{
|
||||||
|
const QString zoneIDStream = file.toString() + u":Zone.Identifier";
|
||||||
|
HANDLE handle = ::CreateFileW(zoneIDStream.toStdWString().c_str(), GENERIC_WRITE
|
||||||
|
, (FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE)
|
||||||
|
, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 5.6.1 Zone.Identifier Stream Name
|
||||||
|
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/6e3f7352-d11c-4d76-8c39-2516a9df36e8
|
||||||
|
const QByteArray zoneID = QByteArrayLiteral("[ZoneTransfer]\r\nZoneId=3\r\n")
|
||||||
|
+ (!url.isEmpty() ? u"HostUrl=%1\r\n"_s.arg(url).toUtf8() : QByteArray());
|
||||||
|
|
||||||
|
DWORD written = 0;
|
||||||
|
const BOOL writeResult = ::WriteFile(handle, zoneID.constData(), zoneID.size(), &written, nullptr);
|
||||||
|
::CloseHandle(handle);
|
||||||
|
|
||||||
|
return writeResult && (written == zoneID.size());
|
||||||
|
}
|
||||||
|
|
||||||
Path Utils::Misc::windowsSystemPath()
|
Path Utils::Misc::windowsSystemPath()
|
||||||
{
|
{
|
||||||
static const Path path = []() -> Path
|
static const Path path = []() -> Path
|
||||||
|
|
|
@ -94,6 +94,7 @@ namespace Utils::Misc
|
||||||
QString languageToLocalizedString(const QString &localeStr);
|
QString languageToLocalizedString(const QString &localeStr);
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
bool applyMarkOfTheWeb(const Path &file, const QString &url = {});
|
||||||
Path windowsSystemPath();
|
Path windowsSystemPath();
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
Loading…
Reference in a new issue