Browse Source

Ask for user confirmation because proceeding with recursive torrent download (security risk)

Fix "add file" dialog in torrent creation tool
adaptive-webui-19844
Christophe Dumez 15 years ago
parent
commit
530fbfc9b4
  1. 7
      src/GUI.cpp
  2. 1
      src/GUI.h
  3. 45
      src/bittorrent.cpp
  4. 2
      src/bittorrent.h
  5. 2
      src/createtorrent_imp.cpp

7
src/GUI.cpp

@ -117,6 +117,7 @@ GUI::GUI(QWidget *parent, QStringList torrentCmdLine) : QMainWindow(parent), dis
connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString))); connect(BTSession, SIGNAL(newDownloadedTorrent(QString, QString)), this, SLOT(processDownloadedFiles(QString, QString)));
connect(BTSession, SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString))); connect(BTSession, SIGNAL(downloadFromUrlFailure(QString, QString)), this, SLOT(handleDownloadFromUrlFailure(QString, QString)));
connect(BTSession, SIGNAL(alternativeSpeedsModeChanged(bool)), this, SLOT(updateAltSpeedsBtn(bool))); connect(BTSession, SIGNAL(alternativeSpeedsModeChanged(bool)), this, SLOT(updateAltSpeedsBtn(bool)));
connect(BTSession, SIGNAL(recursiveTorrentDownloadPossible(QTorrentHandle&)), this, SLOT(askRecursiveTorrentDownloadConfirmation(QTorrentHandle&)));
qDebug("create tabWidget"); qDebug("create tabWidget");
tabs = new QTabWidget(); tabs = new QTabWidget();
@ -413,6 +414,12 @@ void GUI::readParamsOnSocket() {
} }
} }
void GUI::askRecursiveTorrentDownloadConfirmation(QTorrentHandle &h) {
if(QMessageBox::question(this, tr("Recursive download confirmation"), tr("The torrent %1 contains torrent files, do you want to proceed with their download?").arg(h.name()), QMessageBox::Yes|QMessageBox::No) == QMessageBox::Yes) {
BTSession->recursiveTorrentDownload(h);
}
}
void GUI::handleDownloadFromUrlFailure(QString url, QString reason) const{ void GUI::handleDownloadFromUrlFailure(QString url, QString reason) const{
// Display a message box // Display a message box
QMessageBox::critical(0, tr("Url download error"), tr("Couldn't download file at url: %1, reason: %2.").arg(url).arg(reason)); QMessageBox::critical(0, tr("Url download error"), tr("Couldn't download file at url: %1, reason: %2.").arg(url).arg(reason));

1
src/GUI.h

@ -116,6 +116,7 @@ protected slots:
void addUnauthenticatedTracker(const QPair<QTorrentHandle,QString> &tracker); void addUnauthenticatedTracker(const QPair<QTorrentHandle,QString> &tracker);
void processDownloadedFiles(QString path, QString url); void processDownloadedFiles(QString path, QString url);
void finishedTorrent(QTorrentHandle& h) const; void finishedTorrent(QTorrentHandle& h) const;
void askRecursiveTorrentDownloadConfirmation(QTorrentHandle &h);
// Options slots // Options slots
void on_actionOptions_triggered(); void on_actionOptions_triggered();
void optionsSaved(); void optionsSaved();

45
src/bittorrent.cpp

@ -70,13 +70,13 @@ enum VersionType { NORMAL,ALPHA,BETA,RELEASE_CANDIDATE,DEVEL };
// Main constructor // Main constructor
Bittorrent::Bittorrent() Bittorrent::Bittorrent()
: m_scanFolders(ScanFoldersModel::instance(this)), : m_scanFolders(ScanFoldersModel::instance(this)),
preAllocateAll(false), addInPause(false), ratio_limit(-1), preAllocateAll(false), addInPause(false), ratio_limit(-1),
UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false),
DHTEnabled(false), current_dht_port(0), queueingEnabled(false), DHTEnabled(false), current_dht_port(0), queueingEnabled(false),
torrentExport(false), exiting(false) torrentExport(false), exiting(false)
#ifndef DISABLE_GUI #ifndef DISABLE_GUI
, geoipDBLoaded(false), resolve_countries(false) , geoipDBLoaded(false), resolve_countries(false)
#endif #endif
{ {
// To avoid some exceptions // To avoid some exceptions
@ -1814,6 +1814,26 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
#endif #endif
} }
void Bittorrent::recursiveTorrentDownload(const QTorrentHandle &h) {
for(int i=0; i<h.get_torrent_info().num_files(); ++i) {
const QString &torrent_relpath = misc::toQString(h.get_torrent_info().file_at(i).path.string());
if(torrent_relpath.endsWith(".torrent")) {
addConsoleMessage(tr("Recursive download of file %1 embedded in torrent %2", "Recursive download of test.torrent embedded in torrent test2").arg(torrent_relpath).arg(h.name()));
const QString &torrent_fullpath = h.save_path()+QDir::separator()+torrent_relpath;
try {
boost::intrusive_ptr<torrent_info> t = new torrent_info(torrent_fullpath.toLocal8Bit().constData());
const QString &sub_hash = misc::toQString(t->info_hash());
// Passing the save path along to the sub torrent file
TorrentTempData::setSavePath(sub_hash, h.save_path());
addTorrent(torrent_fullpath);
} catch(std::exception&) {
qDebug("Caught error loading torrent");
addConsoleMessage(tr("Unable to decode %1 torrent file.").arg(torrent_fullpath), QString::fromUtf8("red"));
}
}
}
}
// Read alerts sent by the Bittorrent session // Read alerts sent by the Bittorrent session
void Bittorrent::readAlerts() { void Bittorrent::readAlerts() {
// look at session alerts and display some infos // look at session alerts and display some infos
@ -1841,18 +1861,21 @@ void Bittorrent::addConsoleMessage(QString msg, QString) {
const bool was_already_seeded = TorrentPersistentData::isSeed(hash); const bool was_already_seeded = TorrentPersistentData::isSeed(hash);
if(!was_already_seeded) { if(!was_already_seeded) {
h.save_resume_data(); h.save_resume_data();
qDebug("Checking if the torrent contains torrent files to download");
// Check if there are torrent files inside // Check if there are torrent files inside
for(int i=0; i<h.get_torrent_info().num_files(); ++i) { for(int i=0; i<h.get_torrent_info().num_files(); ++i) {
const QString &torrent_relpath = misc::toQString(h.get_torrent_info().file_at(i).path.string()); const QString &torrent_relpath = misc::toQString(h.get_torrent_info().file_at(i).path.string());
if(torrent_relpath.endsWith(".torrent")) { if(torrent_relpath.endsWith(".torrent")) {
addConsoleMessage(tr("Recursive download of file %1 embedded in torrent %2", "Recursive download of test.torrent embedded in torrent test2").arg(torrent_relpath).arg(h.name())); qDebug("Found possible recursive torrent download.");
const QString &torrent_fullpath = h.save_path()+QDir::separator()+torrent_relpath; const QString &torrent_fullpath = h.save_path()+QDir::separator()+torrent_relpath;
qDebug("Full subtorrent path is %s", qPrintable(torrent_fullpath));
try { try {
boost::intrusive_ptr<torrent_info> t = new torrent_info(torrent_fullpath.toLocal8Bit().constData()); boost::intrusive_ptr<torrent_info> t = new torrent_info(torrent_fullpath.toLocal8Bit().constData());
const QString &sub_hash = misc::toQString(t->info_hash()); if(t->is_valid()) {
// Passing the save path along to the sub torrent file qDebug("emitting recursiveTorrentDownloadPossible()");
TorrentTempData::setSavePath(sub_hash, h.save_path()); emit recursiveTorrentDownloadPossible(h);
addTorrent(torrent_fullpath); break;
}
} catch(std::exception&) { } catch(std::exception&) {
qDebug("Caught error loading torrent"); qDebug("Caught error loading torrent");
addConsoleMessage(tr("Unable to decode %1 torrent file.").arg(torrent_fullpath), QString::fromUtf8("red")); addConsoleMessage(tr("Unable to decode %1 torrent file.").arg(torrent_fullpath), QString::fromUtf8("red"));

2
src/bittorrent.h

@ -182,6 +182,7 @@ public slots:
void downloadFromURLList(const QStringList& urls); void downloadFromURLList(const QStringList& urls);
void configureSession(); void configureSession();
void banIP(QString ip); void banIP(QString ip);
void recursiveTorrentDownload(const QTorrentHandle &h);
protected: protected:
QString getSavePath(QString hash, bool fromScanDir = false, QString filePath = QString()); QString getSavePath(QString hash, bool fromScanDir = false, QString filePath = QString());
@ -211,6 +212,7 @@ signals:
void savePathChanged(QTorrentHandle &h); void savePathChanged(QTorrentHandle &h);
void newConsoleMessage(QString msg); void newConsoleMessage(QString msg);
void alternativeSpeedsModeChanged(bool alternative); void alternativeSpeedsModeChanged(bool alternative);
void recursiveTorrentDownloadPossible(QTorrentHandle &h);
private: private:
// Bittorrent // Bittorrent

2
src/createtorrent_imp.cpp

@ -85,7 +85,7 @@ void createtorrent::on_addFolder_button_clicked(){
} }
void createtorrent::on_addFile_button_clicked(){ void createtorrent::on_addFile_button_clicked(){
QString file = QFileDialog::getOpenFileName(this, tr("Select a file to add to the torrent"), QDir::homePath(), QString(), 0, QFileDialog::ShowDirsOnly); QString file = QFileDialog::getOpenFileName(this, tr("Select a file to add to the torrent"), QDir::homePath());
if(!file.isEmpty()) if(!file.isEmpty())
textInputPath->setText(file); textInputPath->setText(file);
} }

Loading…
Cancel
Save