diff --git a/.github/workflows/ci_file_health.yaml b/.github/workflows/ci_file_health.yaml index a46290f53..eb151513c 100644 --- a/.github/workflows/ci_file_health.yaml +++ b/.github/workflows/ci_file_health.yaml @@ -2,6 +2,8 @@ name: CI - File health on: [pull_request, push] +permissions: {} + concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.head_ref != '' }} diff --git a/.github/workflows/ci_macos.yaml b/.github/workflows/ci_macos.yaml index dd0de04ca..181331069 100644 --- a/.github/workflows/ci_macos.yaml +++ b/.github/workflows/ci_macos.yaml @@ -2,6 +2,9 @@ name: CI - macOS on: [pull_request, push] +permissions: + actions: write + concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.head_ref != '' }} @@ -31,6 +34,9 @@ jobs: - name: Install dependencies run: | + export \ + HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 \ + HOMEBREW_NO_INSTALL_CLEANUP=1 brew update > /dev/null brew install \ cmake ninja \ @@ -80,11 +86,12 @@ jobs: - name: Build qBittorrent (Qt5) if: ${{ startsWith(matrix.qt_version, 5) }} run: | + CXXFLAGS="$CXXFLAGS -Werror -Wno-error=deprecated-declarations" \ + LDFLAGS="$LDFLAGS -gz" \ cmake \ -B build \ -G "Ninja" \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_CXX_FLAGS="-Werror -Wno-error=deprecated-declarations" \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DBOOST_ROOT="${{ env.boost_path }}" \ -DOPENSSL_ROOT_DIR="${{ env.openssl_root }}" \ @@ -98,11 +105,12 @@ jobs: - name: Build qBittorrent (Qt6) if: ${{ startsWith(matrix.qt_version, 6) }} run: | + CXXFLAGS="$CXXFLAGS -Wno-gnu-zero-variadic-macro-arguments -Werror -Wno-error=deprecated-declarations" \ + LDFLAGS="$LDFLAGS -gz" \ cmake \ -B build \ -G "Ninja" \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_CXX_FLAGS="-Wno-gnu-zero-variadic-macro-arguments -Werror -Wno-error=deprecated-declarations" \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DBOOST_ROOT="${{ env.boost_path }}" \ -DOPENSSL_ROOT_DIR="${{ env.openssl_root }}" \ diff --git a/.github/workflows/ci_ubuntu.yaml b/.github/workflows/ci_ubuntu.yaml index 053077ef4..f9b0d4181 100644 --- a/.github/workflows/ci_ubuntu.yaml +++ b/.github/workflows/ci_ubuntu.yaml @@ -2,6 +2,9 @@ name: CI - Ubuntu on: [pull_request, push] +permissions: + actions: write + concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.head_ref != '' }} @@ -30,7 +33,7 @@ jobs: sudo apt update sudo apt install \ build-essential cmake ninja-build pkg-config \ - libboost-dev libssl-dev zlib1g-dev + libboost-dev libssl-dev libxkbcommon-x11-dev zlib1g-dev - name: Setup ccache uses: Chocobo1/setup-ccache-action@v1 @@ -65,11 +68,12 @@ jobs: - name: Build qBittorrent (Qt5) if: ${{ startsWith(matrix.qt_version, 5) }} run: | + CXXFLAGS="$CXXFLAGS -Werror -Wno-error=deprecated-declarations" \ + LDFLAGS="$LDFLAGS -gz" \ cmake \ -B build \ -G "Ninja" \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_CXX_FLAGS="-Werror -Wno-error=deprecated-declarations" \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DCMAKE_INSTALL_PREFIX="/usr" \ -DTESTING=ON \ @@ -78,16 +82,17 @@ jobs: cmake --build build --target qbt_update_translations cmake --build build cmake --build build --target check - DESTDIR="qbittorrent" cmake --install build --strip + DESTDIR="qbittorrent" cmake --install build - name: Build qBittorrent (Qt6) if: ${{ startsWith(matrix.qt_version, 6) }} run: | + CXXFLAGS="$CXXFLAGS -Werror" \ + LDFLAGS="$LDFLAGS -gz" \ cmake \ -B build \ -G "Ninja" \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_CXX_FLAGS="-Werror" \ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ -DCMAKE_INSTALL_PREFIX="/usr" \ -DQT6=ON \ @@ -97,7 +102,7 @@ jobs: cmake --build build --target qbt_update_translations cmake --build build cmake --build build --target check - DESTDIR="qbittorrent" cmake --install build --strip + DESTDIR="qbittorrent" cmake --install build - name: Prepare build artifacts run: | diff --git a/.github/workflows/ci_webui.yaml b/.github/workflows/ci_webui.yaml index 18d0e985c..335cfe6ad 100644 --- a/.github/workflows/ci_webui.yaml +++ b/.github/workflows/ci_webui.yaml @@ -2,6 +2,8 @@ name: CI - WebUI on: [pull_request, push] +permissions: {} + concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.head_ref != '' }} diff --git a/.github/workflows/ci_windows.yaml b/.github/workflows/ci_windows.yaml index bca52a8e1..611c1cc2a 100644 --- a/.github/workflows/ci_windows.yaml +++ b/.github/workflows/ci_windows.yaml @@ -2,6 +2,9 @@ name: CI - Windows on: [pull_request, push] +permissions: + actions: write + concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: ${{ github.head_ref != '' }} diff --git a/.github/workflows/coverity-scan.yml b/.github/workflows/coverity-scan.yml index ad243a915..22fbc478e 100644 --- a/.github/workflows/coverity-scan.yml +++ b/.github/workflows/coverity-scan.yml @@ -5,6 +5,8 @@ on: - cron: '0 0 1 * *' # Monthly (1st day of month at midnight) workflow_dispatch: # Mainly for testing. Don't forget the Coverity usage limits. +permissions: {} + jobs: coverity_scan: name: Scan diff --git a/.github/workflows/stale_bot.yaml b/.github/workflows/stale_bot.yaml index 4cb991b87..93fad6070 100644 --- a/.github/workflows/stale_bot.yaml +++ b/.github/workflows/stale_bot.yaml @@ -4,6 +4,9 @@ on: schedule: - cron: '0 0 * * *' +permissions: + pull-requests: write + jobs: stale: runs-on: ubuntu-latest diff --git a/dist/windows/installer-translations/turkish.nsi b/dist/windows/installer-translations/turkish.nsi index 52703fcba..efe92115a 100644 --- a/dist/windows/installer-translations/turkish.nsi +++ b/dist/windows/installer-translations/turkish.nsi @@ -31,7 +31,7 @@ LangString inst_requires_64bit ${LANG_TURKISH} "Bu yükleyici sadece 64-bit Wind ;LangString inst_requires_win7 ${LANG_ENGLISH} "This qBittorrent version requires at least Windows 7." LangString inst_requires_win7 ${LANG_TURKISH} "Bu qBittorrent sürümü en az Windows 7 gerektirir." ;LangString inst_requires_win10 ${LANG_ENGLISH} "This installer requires at least Windows 10 1809." -LangString inst_requires_win10 ${LANG_TURKISH} "This installer requires at least Windows 10 1809." +LangString inst_requires_win10 ${LANG_TURKISH} "Bu yükleyici en az Windows 10 1809 gerektirir." ;LangString inst_uninstall_link_description ${LANG_ENGLISH} "Uninstall qBittorrent" LangString inst_uninstall_link_description ${LANG_TURKISH} "qBittorrent'i kaldır" diff --git a/dist/windows/installer-translations/uzbek.nsi b/dist/windows/installer-translations/uzbek.nsi index 9afba66ff..53cb28ac7 100644 --- a/dist/windows/installer-translations/uzbek.nsi +++ b/dist/windows/installer-translations/uzbek.nsi @@ -1,62 +1,62 @@ ;Installer strings ;LangString inst_qbt_req ${LANG_ENGLISH} "qBittorrent (required)" -LangString inst_qbt_req ${LANG_UZBEK} "qBittorrent (required)" +LangString inst_qbt_req ${LANG_UZBEK} "qBittorrent (talab qilinadi)" ;LangString inst_dekstop ${LANG_ENGLISH} "Create Desktop Shortcut" -LangString inst_dekstop ${LANG_UZBEK} "Create Desktop Shortcut" +LangString inst_dekstop ${LANG_UZBEK} "Ish Stolida Yorliq Yaratilsin" ;LangString inst_startmenu ${LANG_ENGLISH} "Create Start Menu Shortcut" -LangString inst_startmenu ${LANG_UZBEK} "Create Start Menu Shortcut" +LangString inst_startmenu ${LANG_UZBEK} "Boshlash Menyusida Yorliq Yaratilsin" ;LangString inst_startup ${LANG_ENGLISH} "Start qBittorrent on Windows start up" -LangString inst_startup ${LANG_UZBEK} "Start qBittorrent on Windows start up" +LangString inst_startup ${LANG_UZBEK} "qBittorrent Windows bilan birga ishga tushirilsin" ;LangString inst_torrent ${LANG_ENGLISH} "Open .torrent files with qBittorrent" -LangString inst_torrent ${LANG_UZBEK} "Open .torrent files with qBittorrent" +LangString inst_torrent ${LANG_UZBEK} ".torrent fayllar qBittorrent bilan ochilsin" ;LangString inst_magnet ${LANG_ENGLISH} "Open magnet links with qBittorrent" -LangString inst_magnet ${LANG_UZBEK} "Open magnet links with qBittorrent" +LangString inst_magnet ${LANG_UZBEK} "Magnit havolalar qBittorrent bilan ochilsin" ;LangString inst_firewall ${LANG_ENGLISH} "Add Windows Firewall rule" -LangString inst_firewall ${LANG_UZBEK} "Add Windows Firewall rule" +LangString inst_firewall ${LANG_UZBEK} "Windows Xavfsizlik Devori qoidasi qoʻshilsin" ;LangString inst_pathlimit ${LANG_ENGLISH} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)" -LangString inst_pathlimit ${LANG_UZBEK} "Disable Windows path length limit (260 character MAX_PATH limitation, requires Windows 10 1607 or later)" +LangString inst_pathlimit ${LANG_UZBEK} "Windows yoʻl uzunligi cheklovi olib tashlansin (260 belgi MAX_PATH cheklovi, Windows 10 1607 va yuqorisi talab qilinadi)" ;LangString inst_firewallinfo ${LANG_ENGLISH} "Adding Windows Firewall rule" -LangString inst_firewallinfo ${LANG_UZBEK} "Adding Windows Firewall rule" +LangString inst_firewallinfo ${LANG_UZBEK} "Windows Xavfsizlik Devori qoidasini qoʻshish" ;LangString inst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before installing." -LangString inst_warning ${LANG_UZBEK} "qBittorrent is running. Please close the application before installing." +LangString inst_warning ${LANG_UZBEK} "qBittorrent ishga tushgan. Iltimos, oʻrnatishdan oldin dasturni yoping." ;LangString inst_uninstall_question ${LANG_ENGLISH} "Current version will be uninstalled. User settings and torrents will remain intact." -LangString inst_uninstall_question ${LANG_UZBEK} "Current version will be uninstalled. User settings and torrents will remain intact." +LangString inst_uninstall_question ${LANG_UZBEK} "Hozirgi versiya oʻchiriladi. Foydalanuvchi sozlamalari va torrentlar oʻzgarishsiz qoladi." ;LangString inst_unist ${LANG_ENGLISH} "Uninstalling previous version." -LangString inst_unist ${LANG_UZBEK} "Uninstalling previous version." +LangString inst_unist ${LANG_UZBEK} "Oldingi versiyani oʻchirish." ;LangString launch_qbt ${LANG_ENGLISH} "Launch qBittorrent." -LangString launch_qbt ${LANG_UZBEK} "Launch qBittorrent." +LangString launch_qbt ${LANG_UZBEK} "qBittorrent ishga tushirilsin." ;LangString inst_requires_64bit ${LANG_ENGLISH} "This installer works only in 64-bit Windows versions." -LangString inst_requires_64bit ${LANG_UZBEK} "This installer works only in 64-bit Windows versions." +LangString inst_requires_64bit ${LANG_UZBEK} "Bu oʻrnatuvchi faqat Windows 64-bit versiyalarda ishlaydi." ;LangString inst_requires_win7 ${LANG_ENGLISH} "This qBittorrent version requires at least Windows 7." -LangString inst_requires_win7 ${LANG_UZBEK} "This qBittorrent version requires at least Windows 7." +LangString inst_requires_win7 ${LANG_UZBEK} "qBittorrent bu versiyasi kamida Windows 7 talab qiladi." ;LangString inst_requires_win10 ${LANG_ENGLISH} "This installer requires at least Windows 10 1809." -LangString inst_requires_win10 ${LANG_UZBEK} "This installer requires at least Windows 10 1809." +LangString inst_requires_win10 ${LANG_UZBEK} "Bu oʻrnatuvchi kamida Windows 10 1809 talab qiladi." ;LangString inst_uninstall_link_description ${LANG_ENGLISH} "Uninstall qBittorrent" -LangString inst_uninstall_link_description ${LANG_UZBEK} "Uninstall qBittorrent" +LangString inst_uninstall_link_description ${LANG_UZBEK} "qBittorrent oʻchirilsin" ;------------------------------------ ;Uninstaller strings ;LangString remove_files ${LANG_ENGLISH} "Remove files" -LangString remove_files ${LANG_UZBEK} "Remove files" +LangString remove_files ${LANG_UZBEK} "Fayllar oʻchirilsin" ;LangString remove_shortcuts ${LANG_ENGLISH} "Remove shortcuts" -LangString remove_shortcuts ${LANG_UZBEK} "Remove shortcuts" +LangString remove_shortcuts ${LANG_UZBEK} "Yorliqlar oʻchirilsin" ;LangString remove_associations ${LANG_ENGLISH} "Remove file associations" -LangString remove_associations ${LANG_UZBEK} "Remove file associations" +LangString remove_associations ${LANG_UZBEK} "Fayl birlashmalari oʻchirilsin" ;LangString remove_registry ${LANG_ENGLISH} "Remove registry keys" -LangString remove_registry ${LANG_UZBEK} "Remove registry keys" +LangString remove_registry ${LANG_UZBEK} "Reyester kalitlari oʻchirilsin" ;LangString remove_conf ${LANG_ENGLISH} "Remove configuration files" -LangString remove_conf ${LANG_UZBEK} "Remove configuration files" +LangString remove_conf ${LANG_UZBEK} "Sozlama fayllari oʻchirilsin" ;LangString remove_firewall ${LANG_ENGLISH} "Remove Windows Firewall rule" -LangString remove_firewall ${LANG_UZBEK} "Remove Windows Firewall rule" +LangString remove_firewall ${LANG_UZBEK} "Windows Xavfsizlik Devori qoidasi oʻchirilsin" ;LangString remove_firewallinfo ${LANG_ENGLISH} "Removing Windows Firewall rule" -LangString remove_firewallinfo ${LANG_UZBEK} "Removing Windows Firewall rule" +LangString remove_firewallinfo ${LANG_UZBEK} "Windows Xavfsizlik Devori qoidasini oʻchirish" ;LangString remove_cache ${LANG_ENGLISH} "Remove torrents and cached data" -LangString remove_cache ${LANG_UZBEK} "Remove torrents and cached data" +LangString remove_cache ${LANG_UZBEK} "Torrentlar va keshlangan maʼlumotlar oʻchirilsin" ;LangString uninst_warning ${LANG_ENGLISH} "qBittorrent is running. Please close the application before uninstalling." -LangString uninst_warning ${LANG_UZBEK} "qBittorrent is running. Please close the application before uninstalling." +LangString uninst_warning ${LANG_UZBEK} "qBittorrent ishga tushgan. Iltimos, oʻchirishdan oldin dasturni yoping." ;LangString uninst_tor_warn ${LANG_ENGLISH} "Not removing .torrent association. It is associated with:" -LangString uninst_tor_warn ${LANG_UZBEK} "Not removing .torrent association. It is associated with:" +LangString uninst_tor_warn ${LANG_UZBEK} ".torrent birlashmasi oʻchirilmadi. U quyidagi bilan birlashgan:" ;LangString uninst_mag_warn ${LANG_ENGLISH} "Not removing magnet association. It is associated with:" -LangString uninst_mag_warn ${LANG_UZBEK} "Not removing magnet association. It is associated with:" +LangString uninst_mag_warn ${LANG_UZBEK} "Magnit birlashmasi oʻchirilmadi. U quyidagi bilan birlashgan:" diff --git a/src/app/main.cpp b/src/app/main.cpp index bbb293479..fb7d5d12a 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -283,7 +283,7 @@ void showSplashScreen() painter.drawText(224 - painter.fontMetrics().horizontalAdvance(version), 270, version); QSplashScreen *splash = new QSplashScreen(splashImg); splash->show(); - QTimer::singleShot(1500ms, splash, &QObject::deleteLater); + QTimer::singleShot(1500ms, Qt::CoarseTimer, splash, &QObject::deleteLater); qApp->processEvents(); } #endif // DISABLE_GUI diff --git a/src/base/bittorrent/sessionimpl.cpp b/src/base/bittorrent/sessionimpl.cpp index 25a8adfa5..59a1eec9d 100644 --- a/src/base/bittorrent/sessionimpl.cpp +++ b/src/base/bittorrent/sessionimpl.cpp @@ -1050,18 +1050,6 @@ void SessionImpl::setGlobalMaxSeedingMinutes(int minutes) } } -void SessionImpl::adjustLimits() -{ - if (isQueueingSystemEnabled()) - { - lt::settings_pack settingsPack; - // Internally increase the queue limits to ensure that the magnet is started - settingsPack.set_int(lt::settings_pack::active_downloads, adjustLimit(maxActiveDownloads())); - settingsPack.set_int(lt::settings_pack::active_limit, adjustLimit(maxActiveTorrents())); - m_nativeSession->apply_settings(std::move(settingsPack)); - } -} - void SessionImpl::applyBandwidthLimits() { lt::settings_pack settingsPack; @@ -1502,16 +1490,6 @@ void SessionImpl::processBannedIPs(lt::ip_filter &filter) } } -int SessionImpl::adjustLimit(const int limit) const -{ - if (limit <= -1) - return limit; - // check for overflow: (limit + m_extraLimit) < std::numeric_limits::max() - return (m_extraLimit < (std::numeric_limits::max() - limit)) - ? (limit + m_extraLimit) - : std::numeric_limits::max(); -} - void SessionImpl::initMetrics() { const auto findMetricIndex = [](const char *name) -> int @@ -1713,10 +1691,8 @@ lt::settings_pack SessionImpl::loadLTSettings() const // Queueing System if (isQueueingSystemEnabled()) { - // Internally increase the queue limits to ensure that the magnet is started - settingsPack.set_int(lt::settings_pack::active_downloads, adjustLimit(maxActiveDownloads())); - settingsPack.set_int(lt::settings_pack::active_limit, adjustLimit(maxActiveTorrents())); - + settingsPack.set_int(lt::settings_pack::active_downloads, maxActiveDownloads()); + settingsPack.set_int(lt::settings_pack::active_limit, maxActiveTorrents()); settingsPack.set_int(lt::settings_pack::active_seeds, maxActiveUploads()); settingsPack.set_bool(lt::settings_pack::dont_count_slow_torrents, ignoreSlowTorrentsForQueueing()); settingsPack.set_int(lt::settings_pack::inactive_down_rate, downloadRateForSlowTorrents() * 1024); // KiB to Bytes @@ -2290,8 +2266,6 @@ bool SessionImpl::cancelDownloadMetadata(const TorrentID &id) } #endif m_downloadedMetadata.erase(downloadedMetadataIter); - --m_extraLimit; - adjustLimits(); m_nativeSession->remove_torrent(nativeHandle, lt::session::delete_files); return true; } @@ -2839,8 +2813,6 @@ bool SessionImpl::downloadMetadata(const MagnetUri &magnetUri) const auto altID = TorrentID::fromSHA1Hash(infoHash.v1()); m_downloadedMetadata.insert(altID); } - ++m_extraLimit; - adjustLimits(); return true; } @@ -4957,7 +4929,7 @@ void SessionImpl::enqueueRefresh() { Q_ASSERT(!m_refreshEnqueued); - QTimer::singleShot(refreshInterval(), this, [this] () + QTimer::singleShot(refreshInterval(), Qt::CoarseTimer, this, [this] { m_nativeSession->post_torrent_updates(); m_nativeSession->post_session_stats(); @@ -5331,9 +5303,6 @@ void SessionImpl::handleMetadataReceivedAlert(const lt::metadata_received_alert if (found) { const TorrentInfo metadata {*p->handle.torrent_file()}; - - --m_extraLimit; - adjustLimits(); m_nativeSession->remove_torrent(p->handle, lt::session::delete_files); emit metadataDownloaded(metadata); diff --git a/src/base/bittorrent/sessionimpl.h b/src/base/bittorrent/sessionimpl.h index 3d0c3b08d..45b4bf2d8 100644 --- a/src/base/bittorrent/sessionimpl.h +++ b/src/base/bittorrent/sessionimpl.h @@ -475,9 +475,7 @@ namespace BitTorrent lt::settings_pack loadLTSettings() const; void applyNetworkInterfacesSettings(lt::settings_pack &settingsPack) const; void configurePeerClasses(); - int adjustLimit(int limit) const; void initMetrics(); - void adjustLimits(); void applyBandwidthLimits(); void processBannedIPs(lt::ip_filter &filter); QStringList getListeningIPs() const; @@ -668,7 +666,6 @@ namespace BitTorrent const bool m_wasPexEnabled = m_isPeXEnabled; int m_numResumeData = 0; - int m_extraLimit = 0; QVector m_additionalTrackerList; QVector m_excludedFileNamesRegExpList; diff --git a/src/base/bittorrent/torrentimpl.cpp b/src/base/bittorrent/torrentimpl.cpp index 67d0dabbe..596b339fc 100644 --- a/src/base/bittorrent/torrentimpl.cpp +++ b/src/base/bittorrent/torrentimpl.cpp @@ -1441,6 +1441,10 @@ void TorrentImpl::forceRecheck() if (!hasMetadata()) return; m_nativeHandle.force_recheck(); + // We have to force update the cached state, otherwise someone will be able to get + // an incorrect one during the interval until the cached state is updated in a regular way. + m_nativeStatus.state = lt::torrent_status::checking_resume_data; + m_hasMissingFiles = false; m_unchecked = false; m_completedFiles.fill(false); diff --git a/src/base/http/server.cpp b/src/base/http/server.cpp index f53e437d7..e85750c53 100644 --- a/src/base/http/server.cpp +++ b/src/base/http/server.cpp @@ -56,10 +56,33 @@ namespace QList safeCipherList() { const QStringList badCiphers {u"idea"_qs, u"rc4"_qs}; + // Contains Ciphersuites that use RSA for the Key Exchange but they don't mention it in their name + const QStringList badRSAShorthandSuites { + u"AES256-GCM-SHA384"_qs, u"AES128-GCM-SHA256"_qs, u"AES256-SHA256"_qs, + u"AES128-SHA256"_qs, u"AES256-SHA"_qs, u"AES128-SHA"_qs}; + // Contains Ciphersuites that use AES CBC mode but they don't mention it in their name + const QStringList badAESShorthandSuites { + u"ECDHE-ECDSA-AES256-SHA384"_qs, u"ECDHE-RSA-AES256-SHA384"_qs, u"DHE-RSA-AES256-SHA256"_qs, + u"ECDHE-ECDSA-AES128-SHA256"_qs, u"ECDHE-RSA-AES128-SHA256"_qs, u"DHE-RSA-AES128-SHA256"_qs, + u"ECDHE-ECDSA-AES256-SHA"_qs, u"ECDHE-RSA-AES256-SHA"_qs, u"DHE-RSA-AES256-SHA"_qs, + u"ECDHE-ECDSA-AES128-SHA"_qs, u"ECDHE-RSA-AES128-SHA"_qs, u"DHE-RSA-AES128-SHA"_qs}; const QList allCiphers {QSslConfiguration::supportedCiphers()}; QList safeCiphers; - std::copy_if(allCiphers.cbegin(), allCiphers.cend(), std::back_inserter(safeCiphers), [&badCiphers](const QSslCipher &cipher) + std::copy_if(allCiphers.cbegin(), allCiphers.cend(), std::back_inserter(safeCiphers), + [&badCiphers, &badRSAShorthandSuites, &badAESShorthandSuites](const QSslCipher &cipher) { + const QString name = cipher.name(); + if (name.contains(u"-cbc-"_qs, Qt::CaseInsensitive) // AES CBC mode is considered vulnerable to BEAST attack + || name.startsWith(u"adh-"_qs, Qt::CaseInsensitive) // Key Exchange: Diffie-Hellman, doesn't support Perfect Forward Secrecy + || name.startsWith(u"aecdh-"_qs, Qt::CaseInsensitive) // Key Exchange: Elliptic Curve Diffie-Hellman, doesn't support Perfect Forward Secrecy + || name.startsWith(u"psk-"_qs, Qt::CaseInsensitive) // Key Exchange: Pre-Shared Key, doesn't support Perfect Forward Secrecy + || name.startsWith(u"rsa-"_qs, Qt::CaseInsensitive) // Key Exchange: Rivest Shamir Adleman (RSA), doesn't support Perfect Forward Secrecy + || badRSAShorthandSuites.contains(name, Qt::CaseInsensitive) + || badAESShorthandSuites.contains(name, Qt::CaseInsensitive)) + { + return false; + } + return std::none_of(badCiphers.cbegin(), badCiphers.cend(), [&cipher](const QString &badCipher) { return cipher.name().contains(badCipher, Qt::CaseInsensitive); @@ -78,6 +101,7 @@ Server::Server(IRequestHandler *requestHandler, QObject *parent) setProxy(QNetworkProxy::NoProxy); QSslConfiguration sslConf {QSslConfiguration::defaultConfiguration()}; + sslConf.setProtocol(QSsl::TlsV1_2OrLater); sslConf.setCiphers(safeCipherList()); QSslConfiguration::setDefaultConfiguration(sslConf); diff --git a/src/base/torrentfileswatcher.cpp b/src/base/torrentfileswatcher.cpp index 11b04c953..1e56ffbb9 100644 --- a/src/base/torrentfileswatcher.cpp +++ b/src/base/torrentfileswatcher.cpp @@ -503,7 +503,7 @@ void TorrentFilesWatcher::Worker::removeWatchedFolder(const Path &path) void TorrentFilesWatcher::Worker::scheduleWatchedFolderProcessing(const Path &path) { - QTimer::singleShot(2s, this, [this, path]() + QTimer::singleShot(2s, Qt::CoarseTimer, this, [this, path] { processWatchedFolder(path); }); diff --git a/src/webui/api/appcontroller.cpp b/src/webui/api/appcontroller.cpp index e0ddc7d5b..f7a723af8 100644 --- a/src/webui/api/appcontroller.cpp +++ b/src/webui/api/appcontroller.cpp @@ -94,7 +94,7 @@ void AppController::shutdownAction() // Special handling for shutdown, we // need to reply to the Web UI before // actually shutting down. - QTimer::singleShot(100ms, qApp, []() + QTimer::singleShot(100ms, Qt::CoarseTimer, qApp, [] { QCoreApplication::exit(); }); diff --git a/src/webui/www/private/scripts/client.js b/src/webui/www/private/scripts/client.js index c1e3a2c68..a5b6c23f9 100644 --- a/src/webui/www/private/scripts/client.js +++ b/src/webui/www/private/scripts/client.js @@ -1289,11 +1289,11 @@ function registerMagnetHandler() { return; } - const hashParams = getHashParamsFromUrl(); - hashParams.download = ''; - - const templateHashString = Object.toQueryString(hashParams).replace('download=', 'download=%s'); + const hashString = location.hash ? location.hash.replace(/^#/, '') : ''; + const hashParams = new URLSearchParams(hashString); + hashParams.set('download', ''); + const templateHashString = hashParams.toString().replace('download=', 'download=%s'); const templateUrl = location.origin + location.pathname + location.search + '#' + templateHashString; @@ -1313,11 +1313,6 @@ function handleDownloadParam() { showDownloadPage([url]); } -function getHashParamsFromUrl() { - const hashString = location.hash ? location.hash.replace(/^#/, '') : ''; - return (hashString.length > 0) ? String.parseQueryString(hashString) : {}; -} - function closeWindows() { MochaUI.closeAll(); }