From 6eaee82a10b92e26f8b8ab993bee8599289beba7 Mon Sep 17 00:00:00 2001 From: CN_SZTL Date: Sun, 15 Dec 2019 11:07:11 +0800 Subject: [PATCH] Merge source of CTCGFW --- package/lean/UnblockNeteaseMusic/Makefile | 4 +- package/lean/luci-app-qbittorrent/Makefile | 9 +- .../luasrc/controller/qbittorrent.lua | 14 +- .../luasrc/model/cbi/qbittorrent.lua | 399 +- .../view/qbittorrent/qbittorrent_status.htm | 22 + .../po/zh-cn/qbittorrent.po | 529 ++- .../root/etc/config/qbittorrent | 20 +- .../root/etc/init.d/qbittorrent | 295 +- .../root/etc/uci-defaults/luci-qbittorrent | 21 + package/lean/luci-app-ssr-plus/Makefile | 9 +- .../model/cbi/shadowsocksr/client-config.lua | 14 +- .../luasrc/model/cbi/shadowsocksr/log.lua | 5 +- .../luasrc/view/shadowsocksr/ssrurl.htm | 27 +- .../luci-app-ssr-plus/po/zh-cn/ssr-plus.po | 6 +- .../root/etc/init.d/shadowsocksr | 38 +- .../share/shadowsocksr/gentrojanconfig.lua | 38 + package/lean/luci-app-unblockmusic/Makefile | 2 +- .../root/etc/init.d/unblockmusic | 12 +- .../root/lib/upgrade/keep.d/unblockmusic | 3 + .../usr/share/UnblockNeteaseMusic/logcheck.sh | 4 +- .../share/UnblockNeteaseMusic/update_core.sh | 2 +- package/lean/qBittorrent/Makefile | 26 +- .../001-remove-ico-not-for-webui.patch | 126 + .../patches/002-add-autoban-function.patch | 807 ++++ package/lean/qt5/Makefile | 323 +- package/lean/qt5/files/qplatformdefs.h | 40 - .../qt5/patches/010-pre_3.6_kernels_fix.patch | 74 + .../qt5/patches/020-disable_unused_libs.patch | 91 + ...qtbase-fix-compile-with-openssl1.1.1.patch | 3985 +++++++++++++++++ .../mkspecs/linux-openwrt-g++}/qmake.conf | 16 +- .../mkspecs/linux-openwrt-g++/qplatformdefs.h | 9 + package/lienol/ipt2socks/Makefile | 48 + package/lienol/trojan/Makefile | 66 + .../patches/001-force-openssl-version.patch | 11 + 34 files changed, 6731 insertions(+), 364 deletions(-) create mode 100644 package/lean/luci-app-qbittorrent/luasrc/view/qbittorrent/qbittorrent_status.htm create mode 100644 package/lean/luci-app-qbittorrent/root/etc/uci-defaults/luci-qbittorrent create mode 100644 package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/gentrojanconfig.lua create mode 100644 package/lean/luci-app-unblockmusic/root/lib/upgrade/keep.d/unblockmusic create mode 100644 package/lean/qBittorrent/patches/001-remove-ico-not-for-webui.patch create mode 100644 package/lean/qBittorrent/patches/002-add-autoban-function.patch delete mode 100644 package/lean/qt5/files/qplatformdefs.h create mode 100644 package/lean/qt5/patches/010-pre_3.6_kernels_fix.patch create mode 100644 package/lean/qt5/patches/020-disable_unused_libs.patch create mode 100644 package/lean/qt5/patches/030-qtbase-fix-compile-with-openssl1.1.1.patch rename package/lean/qt5/{files => src/qtbase/mkspecs/linux-openwrt-g++}/qmake.conf (66%) create mode 100644 package/lean/qt5/src/qtbase/mkspecs/linux-openwrt-g++/qplatformdefs.h create mode 100644 package/lienol/ipt2socks/Makefile create mode 100644 package/lienol/trojan/Makefile create mode 100644 package/lienol/trojan/patches/001-force-openssl-version.patch diff --git a/package/lean/UnblockNeteaseMusic/Makefile b/package/lean/UnblockNeteaseMusic/Makefile index 6e31863a6e..847d11aff1 100644 --- a/package/lean/UnblockNeteaseMusic/Makefile +++ b/package/lean/UnblockNeteaseMusic/Makefile @@ -11,14 +11,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=UnblockNeteaseMusic -PKG_VERSION:=0.20.4 +PKG_VERSION:=0.22.1 PKG_RELEASE:=1 PKG_LICENSE:=MIT PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/nondanee/UnblockNeteaseMusic.git -PKG_SOURCE_VERSION:=023a97f0e62d322a8d64c59ef3942da7c8a1b546 +PKG_SOURCE_VERSION:=c727245b8de201b91ae859c6ae1412c77ef25cf0 PKG_SOURCE_SUBDIR:=$(PKG_NAME) PKG_SOURCE:=$(PKG_SOURCE_SUBDIR)-$(PKG_VERSION).tar.gz diff --git a/package/lean/luci-app-qbittorrent/Makefile b/package/lean/luci-app-qbittorrent/Makefile index 70f4703b62..343d888466 100644 --- a/package/lean/luci-app-qbittorrent/Makefile +++ b/package/lean/luci-app-qbittorrent/Makefile @@ -1,16 +1,15 @@ # Copyright (C) 2019 Openwrt.org # -# This is a free software, use it under Apache Licene 2.0 & GNU General Public License v3.0. +# This is free software, licensed under the Apache License, Version 2.0 . # include $(TOPDIR)/rules.mk -LUCI_TITLE:=qbittorrent-nox for LuCI -LUCI_DEPENDS:=+qBittorrent +LUCI_TITLE:=LuCI support for qBittorrent +LUCI_DEPENDS:=+qBittorrent +python LUCI_PKGARCH:=all -PKG_NAME:=luci-app-qbittorrent PKG_VERSION=1.0 -PKG_RELEASE:=4 +PKG_RELEASE:=18 include $(TOPDIR)/feeds/luci/luci.mk diff --git a/package/lean/luci-app-qbittorrent/luasrc/controller/qbittorrent.lua b/package/lean/luci-app-qbittorrent/luasrc/controller/qbittorrent.lua index 5363ac9786..77d58b971c 100644 --- a/package/lean/luci-app-qbittorrent/luasrc/controller/qbittorrent.lua +++ b/package/lean/luci-app-qbittorrent/luasrc/controller/qbittorrent.lua @@ -1,4 +1,16 @@ module("luci.controller.qbittorrent",package.seeall) + function index() - entry({"admin","nas","qbittorrent"},cbi("qbittorrent"),_("qbittorrent")) + if not nixio.fs.access("/etc/config/qbittorrent")then + return + end + entry({"admin","nas","qBittorrent"},cbi("qbittorrent"),_("qBittorrent")) + entry({"admin","nas","qBittorrent","status"},call("act_status")).leaf=true end + +function act_status() + local e={} + e.running=luci.sys.call("pgrep qbittorrent-nox >/dev/null")==0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end \ No newline at end of file diff --git a/package/lean/luci-app-qbittorrent/luasrc/model/cbi/qbittorrent.lua b/package/lean/luci-app-qbittorrent/luasrc/model/cbi/qbittorrent.lua index af37d8fb3b..7431394f24 100644 --- a/package/lean/luci-app-qbittorrent/luasrc/model/cbi/qbittorrent.lua +++ b/package/lean/luci-app-qbittorrent/luasrc/model/cbi/qbittorrent.lua @@ -1,44 +1,371 @@ -require("luci.sys") -local e=require"luci.model.uci".cursor() -local o=e:get_first("qbittorrent","Preferences","port")or 8080 + +local o=luci.sys.exec("uci get qbittorrent.main.Port | xargs echo -n") or 8080 + local a=(luci.sys.call("pidof qbittorrent-nox > /dev/null")==0) + local t="" -local e="" if a then -t="      " -end -if a then -e=""..translate("Running").."" -else -e=""..translate("Not running").."" +t="

" end -m = Map("qbittorrent", translate("qbittorrent"), translate("A BT/PT downloader base on Qt")..t -.."

"..translate("qbittorrent Run Status").." : "..e.."
") - -s_basic = m:section(TypedSection, "basic", translate("Basic Settings")) -s_basic.anonymous = true -enable = s_basic:option(Flag, "enable", translate("Enable")) -profile_dir = s_basic:option(Value,"profile_dir",translate("profile_dir"),translate("Store configuration files in the Path")) -profile_dir.default = "/tmp" -program_dir = s_basic:option(Value,"program_dir",translate("program_dir"),translate("Store Program files in the Path")) -program_dir.default = "/usr/bin" -library_dir = s_basic:option(Value,"library_dir",translate("library_dir"),translate("Store Library in the Path")) -library_dir.default = "/usr/lib" - -s_download = m:section(TypedSection, "Preferences", translate("Download Settings")) -s_download.anonymous = true -download_dir = s_download:option(Value,"download_dir",translate("download_dir"),translate("Store download files in the Path")) -download_dir.default = "/tmp/download" - -s_webui = m:section(TypedSection, "Preferences", translate("WEBUI Settings")) -s_webui.anonymous = true -port = s_webui:option(Value,"port",translate("port"),translate("WEBUI listening port")) -port.default = "8080" - -local apply = luci.http.formvalue("cbi.apply") -if apply then - io.popen("/etc/init.d/qbittorrent restart") +function titlesplit(Value) + return "

" .. translate(Value) .. "

" end +m = Map("qbittorrent", translate("qBittorrent"), translate("qBittorrent is a cross-platform free and open-source BitTorrent client")..t) + +s = m:section(NamedSection, "main", "qbittorrent") + +s:tab("basic", translate("Basic Settings")) + +o = s:taboption("basic", Flag, "enabled", translate("Enabled")) +o.default = "1" + +o = s:taboption("basic", ListValue, "user", translate("Run daemon as user")) +local u +for u in luci.util.execi("cat /etc/passwd | cut -d ':' -f1") do + o:value(u) +end + +o = s:taboption("basic", Value, "profile", translate("Store configuration files in the Path")) +o.default = '/tmp' + +o = s:taboption("basic", Value, "SavePath", translate("Store download files in the Path")) +o.placeholder = "/tmp/download" + +o = s:taboption("basic", Value, "Port", translate("WEBUI listening port")) +o.datatype = "port" +o.placeholder = "8080" + +o = s:taboption("basic", Flag, "UseRandomPort", translate("Use Random Port"), translate("Randomly assigns a different port every time qBittorrent starts up")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("basic", Value, "PortRangeMin", translate("Connection Port"), translate("Incoming connection port")) +o:depends("UseRandomPort", false) +o.datatype = "range(1024,65535)" + + +s:tab("connection", translate("Connection Settings")) + +o = s:taboption("connection", Flag, "UPnP", translate("Use UPnP for Connections"), translate("Use UPnP/ NAT-PMP port forwarding from my router. Refer to the " + .. "wiki.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + + +o = s:taboption("connection", Value, "GlobalDLLimit", translate("Global Download Speed"), translate("Global Download Speed Limit(KiB/s).")) +o.datatype = "float" +o.placeholder = "0" + +o = s:taboption("connection", Value, "GlobalUPLimit", translate("Global Upload Speed"), translate("Global Upload Speed Limit(KiB/s).")) +o.datatype = "float" +o.placeholder = "0" + +o = s:taboption("connection", Value, "GlobalDLLimitAlt", translate("Alternative Download Speed"), translate("Alternative Download Speed Limit(KiB/s).")) +o.datatype = "float" +o.placeholder = "10" + +o = s:taboption("connection", Value, "GlobalUPLimitAlt", translate("Alternative Upload Speed"), translate("Alternative Upload Speed Limit(KiB/s).")) +o.datatype = "float" +o.placeholder = "10" + +o = s:taboption("connection", ListValue, "BTProtocol", translate("Enabled protocol"), translate("The protocol that was enabled.")) +o:value("Both", translate("TCP and UTP")) +o:value("TCP", translate("TCP")) +o:value("UTP", translate("UTP")) +o.default = "Both" + +o = s:taboption("connection", Value, "InetAddress", translate("Inet Address"), translate("The address that respond to the trackers.")) + +s:tab("downloads", translate("Download Settings")) + +o = s:taboption("downloads", Flag, "CreateTorrentSubfolder", translate("Create Subfolder"), translate("Create subfolder for torrents with multiple files.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("downloads", Flag, "StartInPause", translate("Start In Pause"), translate("Do not start the download automatically.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.disabled + +o = s:taboption("downloads", Flag, "AutoDeleteAddedTorrentFile", translate("Auto Delete Torrent File"), translate("The .torrent files will be deleted afterwards.")) +o.enabled = "IfAdded" +o.disabled = "Never" +o.default = o.disabled + +o = s:taboption("downloads", Flag, "PreAllocation", translate("Pre Allocation"), translate("Pre-allocate disk space for all files.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.disabled + +o = s:taboption("downloads", Flag, "UseIncompleteExtension", translate("Use Incomplete Extension"), translate("The incomplete task will be added the extension of !qB.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.disabled + +o = s:taboption("downloads", Flag, "TempPathEnabled", translate("Temp Path Enabled")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("downloads", Value, "TempPath", translate("Temp Path"), translate("The absolute and relative path can be set.")) +o:depends("TempPathEnabled", "true") +o.placeholder = "temp/" + +o = s:taboption("downloads", Value, "DiskWriteCacheSize", translate("Disk Cache Size (MiB)"), translate("The value -1 is auto and 0 is disable. In default, it is set to 64MiB.")) +o.datatype = "integer" +o.placeholder = "64" + +o = s:taboption("downloads", Value, "DiskWriteCacheTTL", translate("Disk Cache TTL (s)"), translate("In default, it is set to 60s.")) +o.datatype = "integer" +o.placeholder = "60" + +o = s:taboption("downloads", DummyValue, "Saving Management", titlesplit("Saving Management")) + +o = s:taboption("downloads", ListValue, "DisableAutoTMMByDefault", translate("Default Torrent Management Mode")) +o:value("true", translate("Manual")) +o:value("false", translate("Automaic")) +o.default = "true" + +o = s:taboption("downloads", ListValue, "CategoryChanged", translate("Torrent Category Changed"), translate("Choose the action when torrent category changed.")) +o:value("true", translate("Switch torrent to Manual Mode")) +o:value("false", translate("Relocate torrent")) +o.default = "false" + +o = s:taboption("downloads", ListValue, "DefaultSavePathChanged", translate("Default Save Path Changed"), translate("Choose the action when default save path changed.")) +o:value("true", translate("Switch affected torrent to Manual Mode")) +o:value("false", translate("Relocate affected torrent")) +o.default = "true" + +o = s:taboption("downloads", ListValue, "CategorySavePathChanged", translate("Category Save Path Changed"), translate("Choose the action when category save path changed.")) +o:value("true", translate("Switch affected torrent to Manual Mode")) +o:value("false", translate("Relocate affected torrent")) +o.default = "true" + +o = s:taboption("downloads", Value, "TorrentExportDir", translate("Torrent Export Dir"), translate("The .torrent files will be copied to the target directory.")) + +o = s:taboption("downloads", Value, "FinishedTorrentExportDir", translate("Finished Torrent Export Dir"), translate("The .torrent files for finished downloads will be copied to the target directory.")) + +s:tab("bittorrent", translate("Bittorrent Settings")) + +o = s:taboption("bittorrent", Flag, "DHT", translate("Enable DHT"), translate("Enable DHT (decentralized network) to find more peers")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("bittorrent", Flag, "PeX", translate("Enable PeX"), translate("Enable Peer Exchange (PeX) to find more peers")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("bittorrent", Flag, "LSD", translate("Enable LSD"), translate("Enable Local Peer Discovery to find more peers")) +o.enabled = "true" +o.disabled = "false" +o.default = o.disabled + +o = s:taboption("bittorrent", Flag, "uTP_rate_limited", translate("uTP Rate Limit"), translate("Apply rate limit to μTP protocol.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("bittorrent", ListValue, "Encryption", translate("Encryption Mode"), translate("Enable DHT (decentralized network) to find more peers")) +o:value("0", translate("Prefer Encryption")) +o:value("1", translate("Require Encryption")) +o:value("2", translate("Disable Encryption")) +o.default = "0" + +o = s:taboption("bittorrent", Value, "MaxConnecs", translate("Max Connections"), translate("The max number of connections.")) +o.datatype = "integer" +o.placeholder = "500" + +o = s:taboption("bittorrent", Value, "MaxConnecsPerTorrent", translate("Max Connections Per Torrent"), translate("The max number of connections per torrent.")) +o.datatype = "integer" +o.placeholder = "100" + +o = s:taboption("bittorrent", Value, "MaxUploads", translate("Max Uploads"), translate("The max number of connected peers.")) +o.datatype = "integer" +o.placeholder = "8" + +o = s:taboption("bittorrent", Value, "MaxUploadsPerTorrent", translate("Max Uploads Per Torrent"), translate("The max number of connected peers per torrent.")) +o.datatype = "integer" +o.placeholder = "4" + +o = s:taboption("bittorrent", Value, "MaxRatio", translate("Max Ratio"), translate("The max ratio for seeding. -1 is to disable the seeding.")) +o.datatype = "float" +o.placeholder = "-1" + +o = s:taboption("bittorrent", ListValue, "MaxRatioAction", translate("Max Ratio Action"), translate("The action when reach the max seeding ratio.")) +o:value("0", translate("Pause them")) +o:value("1", translate("Remove them")) +o.defaule = "0" + +o = s:taboption("bittorrent", Value, "GlobalMaxSeedingMinutes", translate("Max Seeding Minutes"), translate("Units: minutes")) +o.datatype = "integer" + +o = s:taboption("bittorrent", DummyValue, "Queueing Setting", titlesplit("Queueing Setting")) + +o = s:taboption("bittorrent", Flag, "QueueingEnabled", translate("Enable Torrent Queueing")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("bittorrent", Value, "MaxActiveDownloads", translate("Maximum Active Downloads")) +o.datatype = "integer" +o.placeholder = "3" + +o = s:taboption("bittorrent", Value, "MaxActiveUploads", translate("Max Active Uploads")) +o.datatype = "integer" +o.placeholder = "3" + +o = s:taboption("bittorrent", Value, "MaxActiveTorrents", translate("Max Active Torrents")) +o.datatype = "integer" +o.placeholder = "5" + +o = s:taboption("bittorrent", Flag, "IgnoreSlowTorrents", translate("Ignore Slow Torrents"), translate("Do not count slow torrents in these limits.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.disabled + +o = s:taboption("bittorrent", Value, "SlowTorrentsDownloadRate", translate("Download rate threshold"), translate("Units: KiB/s")) +o.datatype = "integer" +o.placeholder = "2" + +o = s:taboption("bittorrent", Value, "SlowTorrentsUploadRate", translate("Upload rate threshold"), translate("Units: KiB/s")) +o.datatype = "integer" +o.placeholder = "2" + +o = s:taboption("bittorrent", Value, "SlowTorrentsInactivityTimer", translate("Torrent inactivity timer"), translate("Units: seconds")) +o.datatype = "integer" +o.placeholder = "60" + +s:tab("webgui", translate("WebUI Settings")) + +o = s:taboption("webgui", Flag, "UseUPnP", translate("Use UPnP for WebUI"), translate("Using the UPnP / NAT-PMP port of the router for connecting to WebUI.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.disabled + +o = s:taboption("webgui", Value, "Username", translate("Username"), translate("The login name for WebUI.")) +o.placeholder = "admin" + +o = s:taboption("webgui", Value, "Password", translate("Password"), translate("The login password for WebUI.")) +o.password = true + +o = s:taboption("webgui", Value, "Locale", translate("Locale Language")) +o:value("en", translate("English")) +o:value("zh", translate("Chinese")) +o.default = "en" + +o = s:taboption("webgui", Flag, "CSRFProtection", translate("CSRF Protection"), translate("Enable Cross-Site Request Forgery (CSRF) protection.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("webgui", Flag, "ClickjackingProtection", translate("Clickjacking Protection"), translate("Enable clickjacking protection.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("webgui", Flag, "HostHeaderValidation", translate("Host Header Validation"), translate("Validate the host header.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("webgui", Flag, "LocalHostAuth", translate("Local Host Authentication"), translate("Force authentication for clients on localhost.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("webgui", Flag, "AuthSubnetWhitelistEnabled", translate("Enable Subnet Whitelist")) +o.enabled = "true" +o.disabled = "false" +o.default = o.disabled + +o = s:taboption("webgui", DynamicList, "AuthSubnetWhitelist", translate("Subnet Whitelist")) +o:depends("AuthSubnetWhitelistEnabled", "true") + +s:tab("advanced", translate("Advance Settings")) + +o = s:taboption("advanced", Flag, "AnonymousMode", translate("Anonymous Mode"), translate("When enabled, qBittorrent will take certain measures to try" + .. " to mask its identity. Refer to the wiki")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("advanced", Flag, "SuperSeeding", translate("Super Seeding"), translate("The super seeding mode.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.disabled + +o = s:taboption("advanced", Value, "configuration", translate("Profile Folder Suffix"), translate("Suffix for profile folder")) + +o = s:taboption("advanced", Flag, "IncludeOverhead", translate("Limit Overhead Usage"), translate("The overhead usage is been limitted.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.disabled + +o = s:taboption("advanced", Flag, "IgnoreLimitsLAN", translate("Ignore LAN Limit"), translate("Ignore the speed limit to LAN.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("advanced", Flag, "osCache", translate("Use os Cache")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("advanced", Value, "OutgoingPortsMax", translate("Max Outgoing Port"), translate("The max outgoing port.")) +o.datatype = "port" + +o = s:taboption("advanced", Value, "OutgoingPortsMin", translate("Min Outgoing Port"), translate("The min outgoing port.")) +o.datatype = "port" + +o = s:taboption("advanced", ListValue, "SeedChokingAlgorithm", translate("Choking Algorithm"), translate("The strategy of choking algorithm.")) +o:value("RoundRobin", translate("Round Robin")) +o:value("FastestUpload", translate("Fastest Upload")) +o:value("AntiLeech", translate("Anti-Leech")) +o.default = "FastestUpload" + +o = s:taboption("advanced", Flag, "AnnounceToAllTrackers", translate("Announce To All Trackers")) +o.enabled = "true" +o.disabled = "false" +o.default = o.disabled + +o = s:taboption("advanced", Flag, "AnnounceToAllTiers", translate("Announce To All Tiers")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("advanced", Flag, "Enabled", translate("Enable Log"), translate("Enable logger to log file.")) +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("advanced", Value, "Path", translate("Log Path"), translate("The path for qbittorrent log.")) +o:depends("Enabled", "true") + +o = s:taboption("advanced", Flag, "Backup", translate("Enable Backup"), translate("Backup log file when oversize the given size.")) +o:depends("Enabled", "true") +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("advanced", Flag, "DeleteOld", translate("Delete Old Backup"), translate("Delete the old log file.")) +o:depends("Enabled", "true") +o.enabled = "true" +o.disabled = "false" +o.default = o.enabled + +o = s:taboption("advanced", Value, "MaxSizeBytes", translate("Log Max Size"), translate("The max size for qbittorrent log (Unit: Bytes).")) +o:depends("Enabled", "true") +o.placeholder = "66560" + +o = s:taboption("advanced", Value, "SaveTime", translate("Log Saving Period"), translate("The log file will be deteted after given time. 1d -- 1 day, 1m -- 1 month, 1y -- 1 year")) +o:depends("Enabled", "true") +o.datatype = "string" + return m diff --git a/package/lean/luci-app-qbittorrent/luasrc/view/qbittorrent/qbittorrent_status.htm b/package/lean/luci-app-qbittorrent/luasrc/view/qbittorrent/qbittorrent_status.htm new file mode 100644 index 0000000000..13ebe1c978 --- /dev/null +++ b/package/lean/luci-app-qbittorrent/luasrc/view/qbittorrent/qbittorrent_status.htm @@ -0,0 +1,22 @@ + + +
+

+ <%:Collecting data...%> +

+
\ No newline at end of file diff --git a/package/lean/luci-app-qbittorrent/po/zh-cn/qbittorrent.po b/package/lean/luci-app-qbittorrent/po/zh-cn/qbittorrent.po index d7a834ede1..001a33f599 100644 --- a/package/lean/luci-app-qbittorrent/po/zh-cn/qbittorrent.po +++ b/package/lean/luci-app-qbittorrent/po/zh-cn/qbittorrent.po @@ -1,5 +1,5 @@ msgid "qbittorrent" -msgstr "BT下载器-qb" +msgstr "qbittorrent" msgid "Running" msgstr "运行中" @@ -16,8 +16,8 @@ msgstr "基本设置" msgid "Enable" msgstr "启用" -msgid "A BT/PT downloader base on Qt" -msgstr "一个基于QT的BT/PT下载器" +msgid "qBittorrent is a cross-platform free and open-source BitTorrent client" +msgstr "qBittorrent是一个基于 QT 的跨平台的开源 BitTorrent 客户端" msgid "profile_dir" msgstr "配置文件目录" @@ -50,4 +50,525 @@ msgid "WEBUI Settings" msgstr "WEBUI设置" msgid "WEBUI listening port" -msgstr "WEBUI监听端口" +msgstr "WebUI 监听端口" + +msgid "Use Random Port" +msgstr "随机传入连接端口" + +msgid "Randomly assigns a different port every time qBittorrent starts up" +msgstr "在每次启动时使用不同的传入连接端口" + +msgid "Connection Port" +msgstr "用于传入连接的端口" + +msgid "Incoming connection port" +msgstr "推荐在防火墙 -> 流量规则 中,打开这个端口获得更好的下载速度( TCP+UDP )" + +msgid "Bittorrent Settings" +msgstr "Bittorrent 设置" + +msgid "WebUI Settings" +msgstr "WebUI 设置" + +msgid "Advance Settings" +msgstr "高级设置" + + +msgid "Run daemon as user" +msgstr "用户组" + +msgid "Parent Path for Profile Folder" +msgstr "配置保存路径" + +msgid "The path for storing profile folder using by command: --profile [PATH]." +msgstr "配置文件的保存路径,默认的配置文件夹在/tmp下。例如:/etc/config" + +msgid "Profile Folder Suffix" +msgstr "配置目录后缀" + +msgid "Suffix for profile folder, for example, qBittorrent_[NAME]." +msgstr "配置文件文件夹的后缀。例如: qBittorrent_[NAME]" + +msgid "Locale Language" +msgstr "WebUI语言" + +msgid "English" +msgstr "英文" + +msgid "Chinese" +msgstr "中文" + +msgid "Enable Log" +msgstr "启用日志" + +msgid "Enable logger to log file." +msgstr "qBittorrent的启动和运行信息文档。" + +msgid "Log Path" +msgstr "日志文件" + +msgid "The path for qbittorrent log." +msgstr "日志文件自定义保存路径,默认都在配置文件夹的data下。" + +msgid "Enable Backup" +msgstr "启用备份" + +msgid "Backup log file when oversize the given size." +msgstr "备份日志文件。" + +msgid "Delete Old Backup" +msgstr "删除备份" + +msgid "Delete the old log file." +msgstr "符合下列设定后将删除旧的日志文件。" + +msgid "Log Max Size" +msgstr "日志保存大小" + +msgid "Log Saving Period" +msgstr "日志保存期限" + +msgid "The max size for qbittorrent log (Unit: Bytes)." +msgstr "设定日志文件的大小(单位:字节)" + +msgid "The log file will be deteted after given time. 1d -- 1 day, 1m -- 1 month, 1y -- 1 year" +msgstr "设定日志文件的时间(1d-1天,1m-1个月,1y-1年)" + +msgid "Connection Settings" +msgstr "连接设置" + +msgid "Use UPnP for Connections" +msgstr "端口自动转发" + +msgid "Use UPnP/ NAT-PMP port forwarding from my router." +msgstr "使用路由器的UPnP/NAT-PMP端口自动转发。" + +msgid "Use Random Port" +msgstr "启用随机端口" + +msgid "Use different port on each startup voids the first" +msgstr "在每次启动时使用随机的端口。" + +msgid "Connection Port" +msgstr "自定义端口" + +msgid "Generate Randomly" +msgstr "默认端口:8999" + +msgid "Global Download Speed" +msgstr "全局下载速度限制" + +msgid "Global Download Speed Limit(KiB/s)." +msgstr "全局下载速度限制(KiB/s),0为无限制。" + +msgid "Global Upload Speed" +msgstr "全局上传速度限制" + +msgid "Alternative Download Speed" +msgstr "备用下载速度限制" + +msgid "Alternative Upload Speed" +msgstr "备用上传速度限制" + +msgid "Global Upload Speed Limit(KiB/s)." +msgstr "全局上传速度限制(KiB/s),0为无限制。" + +msgid "Alternative Download Speed Limit(KiB/s)." +msgstr "备用下载速度限制(KiB/s),0为无限制。" + +msgid "Alternative Upload Speed Limit(KiB/s)." +msgstr "备用上传速度限制(KiB/s),0为无限制。" + +msgid "Enabled protocol" +msgstr "启用的协议" + +msgid "The protocol that was enabled." +msgstr "当前已启用的协议。" + +msgid "TCP and UTP" +msgstr "TCP和UTP" + +msgid "Inet Address" +msgstr "输入地址" + +msgid "The address that respond to the trackers." +msgstr "响应跟踪器的地址。" + +msgid "When adding seeds" +msgstr "当添加种子时" + +msgid "Downloads Settings" +msgstr "下载设置" + +msgid "Create Subfolder" +msgstr "创建目录" + +msgid "Create subfolder for torrents with multiple files." +msgstr "为含多个文件的种子创建子文件夹。" + +msgid "Start In Pause" +msgstr "开始暂停" + +msgid "Do not start the download automatically." +msgstr "在下载任务添加后暂停。" + +msgid "Auto Delete Torrent File" +msgstr "删除种子" + +msgid "The .torrent files will be deleted afterwards." +msgstr "下载完成后自动删除这个种子文件。" + +msgid "Pre Allocation" +msgstr "磁盘预分配" + +msgid "Pre-allocate disk space for all files." +msgstr "为刚添加的文件预先分配磁盘空间。" + +msgid "Use Incomplete Extension" +msgstr "使用扩展名" + +msgid "The incomplete task will be added the extension of !qB." +msgstr "为不完整的文件添加后缀名!qB" + +msgid "Save Path" +msgstr "文件保存路径" + +msgid "The path to save the download file. For example:/mnt/sda1/download" +msgstr "下载文件的保存路径。例如:/mnt/sda1/download" + +msgid "Temp Path Enabled" +msgstr "启用临时目录" + +msgid "Temp Path" +msgstr "临时路径" + +msgid "The absolute and relative path can be set." +msgstr "可以设置绝对和相对路径。" + +msgid "Disk Cache Size (MiB)" +msgstr "磁盘缓存" + +msgid "The value -1 is auto and 0 is disable. In default, it is set to 64MiB." +msgstr "数值1是自动的,0是禁用的。默认设置为64MiB。" + +msgid "Disk Cache TTL (s)" +msgstr "磁盘缓存TTL" + +msgid "In default, it is set to 60s." +msgstr "默认设置为60秒。" + +msgid "Saving Management" +msgstr "保存管理" + +msgid "Default Torrent Management Mode" +msgstr "默认种子管理模式" + +msgid "Manual" +msgstr "手动" + +msgid "Automaic" +msgstr "自动" + +msgid "Torrent Category Changed" +msgstr "当种子分类修改时" + +msgid "Choose the action when torrent category changed." +msgstr "选择种子类别更改时的操作。" + +msgid "Switch torrent to Manual Mode" +msgstr "将种子切换到手动模式" + +msgid "Relocate torrent" +msgstr "重新定位种子" + +msgid "Default Save Path Changed" +msgstr "当默认保存路径修改时" + +msgid "Choose the action when default save path changed." +msgstr "选择默认保存路径更改时的操作。" + +msgid "Switch affected torrent to Manual Mode" +msgstr "将受影响的种子切换到手动模式" + +msgid "Relocate affected torrent" +msgstr "重新定位种子" + +msgid "Category Save Path Changed" +msgstr "当分类保存路径修改时" + +msgid "Choose the action when category save path changed." +msgstr "选择分类保存路径更改时的操作。" + +msgid "Torrent Export Dir" +msgstr "种子导出目录" + +msgid "The .torrent files will be copied to the target directory." +msgstr "种子文件将被复制到目标目录。例如:/etc/config" + +msgid "Finished Torrent Export Dir" +msgstr "复制种子文件" + +msgid "The .torrent files for finished downloads will be copied to the target directory." +msgstr "将已下载完成的种子文件复制到目标目录。例如:/etc/config" + +msgid "Bittorrent Settings" +msgstr "BT设置"" + +msgid "Enable DHT" +msgstr "启用DHT" + +msgid "Enable DHT (decentralized network) to find more peers" +msgstr "启用DHT(去中心化网络) 以找到更多用户。" + +msgid "Enable PeX" +msgstr "启用PeX" + +msgid "Enable Peer Exchange (PeX) to find more peers" +msgstr "启用用户交换(PeX)以找到更多用户。" + +msgid "Enable LSD" +msgstr "启用LSD" + +msgid "Enable Local Peer Discovery to find more peers" +msgstr "启用本地用户发现以找到更多用户。" + +msgid "uTP Rate Limit" +msgstr "uTP速度限制" + +msgid "Apply rate limit to µTP protocol." +msgstr "针对µTP协议进行速度限制。" + +msgid "Encryption Mode" +msgstr "加密模式" + +msgid "Enable DHT (decentralized network) to find more peers" +msgstr "使DHT(分散网络)能够找到更多的对等点。" + +msgid "Prefer Encryption" +msgstr "偏好加密" + +msgid "Require Encryption" +msgstr "强制加密" + +msgid "Disable Encryption" +msgstr "禁用加密" + +msgid "Max Connections" +msgstr "连接数限制" + +msgid "The max number of connections." +msgstr "全局最大连接数。" + +msgid "Max Connections Per Torrent" +msgstr "种子连接数限制" + +msgid "The max number of connections per torrent." +msgstr "每个种子的最大连接数。" + +msgid "Max Uploads" +msgstr "最大上传数" + +msgid "The max number of connected peers." +msgstr "全局最大上传线程数。" + +msgid "Max Uploads Per Torrent" +msgstr "种子上传限制" + +msgid "The max number of connected peers per torrent." +msgstr "每个种子上传线程最大值。" + +msgid "Share rate limit" +msgstr "分享率限制" + +msgid "Max Ratio" +msgstr "最大的分享率" + +msgid "The max ratio for seeding. -1 is to disable the seeding." +msgstr "分享的最大比例设定。-1是禁用做种。" + +msgid "Max Seeding Minutes" +msgstr "最大做种时间" + +msgid "Units: minutes" +msgstr "做种最大比例设定。单位:分钟" + +msgid "Max Ratio Action" +msgstr "达到后" + +msgid "The action when reach the max seeding ratio." +msgstr "达到设定分享率和时间后的动作。" + +msgid "Pause them" +msgstr "暂停" + +msgid "Remove them" +msgstr "删除" + +msgid "Queueing Setting" +msgstr "种子排队设置" + +msgid "Enable Torrent Queueing" +msgstr "启用种子排队" + +msgid "Maximum Active Downloads" +msgstr "最大活动的下载数" + +msgid "Max Active Uploads" +msgstr "最大活动的上传数" + +msgid "Max Active Torrents" +msgstr "最大活动的种子数" + +msgid "Ignore Slow Torrents" +msgstr "忽略慢速的种子" + +msgid "Do not count slow torrents in these limits." +msgstr "慢速的种子不包在括限制内。" + +msgid "Download rate threshold" +msgstr "下载速度阈值" + +msgid "Upload rate threshold" +msgstr "上传速度阈值" + +msgid "Units: KiB/s" +msgstr "单位:KiB/s" + +msgid "Torrent inactivity timer" +msgstr "种子不活动时间" + +msgid "Units: seconds" +msgstr "时间单位:分钟" + +msgid "WebUI Settings" +msgstr "WebUI设置" + +msgid "Username" +msgstr "" + +msgid "Password" +msgstr "" + +msgid "Use UPnP for WebUI" +msgstr "WebUI端口转发" + +msgid "Using the UPnP / NAT-PMP port of the router for connecting to WebUI." +msgstr "使用路由器的UPnP/NAT-PMP端口转发到WebUI。" + +msgid "The login name for WebUI." +msgstr "WebUI的登录用户名设置。" + +msgid "The login password for WebUI." +msgstr "WebUI用户的登录密码设置。" + +msgid "The listening port for WebUI." +msgstr "WebUI的登录端口设置。默认端口:8080" + +msgid "CSRF Protection" +msgstr "CSRF保护" + +msgid "Enable Cross-Site Request Forgery (CSRF) protection." +msgstr "启用跨站点请求伪造(CSRF)保护。" + +msgid "Clickjacking Protection" +msgstr "劫持保护" + +msgid "Enable clickjacking protection." +msgstr "启用点击劫持保护。" + +msgid "Host Header Validation" +msgstr "主机标头验证" + +msgid "Validate the host header." +msgstr "启用主机标头验证." + +msgid "Local Host Authentication" +msgstr "本地主机认证" + +msgid "Force authentication for clients on localhost." +msgstr "强制对本地主机上的客户端进行身份验证。" + +msgid "Enable Subnet Whitelist" +msgstr "使子网白名单" + +msgid "Subnet Whitelist" +msgstr "输入IP地址" + +msgid "Skip authentication for clients in the IP subnet white list." +msgstr "对IP子网白名单中的客户端跳过身份验证." + +msgid "Advance Settings" +msgstr "高级设置" + +msgid "Anonymous Mode" +msgstr "匿名模式" + +msgid "When enabled, qBittorrent will take certain measures to try" +msgstr "启用后,qBittorrent将采取某些措施隐藏其身份。" + +msgid "Super Seeding" +msgstr "超级种子" + +msgid "The super seeding mode." +msgstr "超级种子模式。" + +msgid "Limit Overhead Usage" +msgstr "开销限制" + +msgid "The overhead usage is been limitted." +msgstr "对传送总开销进行速度限制。" + +msgid "Ignore LAN Limit" +msgstr "LAN限制" + +msgid "Ignore the speed limit to LAN." +msgstr "忽略对LAN的速度限制。" + +msgid "Use os Cache" +msgstr "使用OS操作系统缓存管理" + +msgid "Max Outgoing Port" +msgstr "端口设置" + +msgid The max outgoing port."" +msgstr "最大输出端口。" + +msgid "Min Outgoing Port" +msgstr "端口设置" + +msgid "The min outgoing port." +msgstr "最小输出端口。" + +msgid "Choking Algorithm" +msgstr "数据传输算法" + +msgid "The strategy of choking algorithm." +msgstr "数据传输算法的策略。" + +msgid "Round Robin" +msgstr "负载均衡" + +msgid "Fastest Upload" +msgstr "最快上传" + +msgid "Anti-Leech" +msgstr "反吸血" + +msgid "Announce To All Trackers" +msgstr "对所有Trackers宣告" + +msgid "Announce To All Tiers" +msgstr "对所有Tiers宣告" + +msgid "configuration file" +msgstr "配置文件" + +msgid "Operation log" +msgstr "运行日志" + +msgid "This page is the log document content of qbittorrent." +msgstr "本页是qBittorrent的日志文档内容。" + +msgid "This page is the content of the configuration document under /etc/config/qbittorrent." +msgstr "本页是/etc/config/qbittorrent下的配置文档内容。" + diff --git a/package/lean/luci-app-qbittorrent/root/etc/config/qbittorrent b/package/lean/luci-app-qbittorrent/root/etc/config/qbittorrent index b4fe940c3c..4ec138ff67 100644 --- a/package/lean/luci-app-qbittorrent/root/etc/config/qbittorrent +++ b/package/lean/luci-app-qbittorrent/root/etc/config/qbittorrent @@ -1,3 +1,19 @@ -config basic -config Preferences + +config qbittorrent 'main' + option user 'root' + option Locale 'zh' + option BTProtocol 'Both' + option DisableAutoTMMByDefault 'true' + option CategoryChanged 'false' + option DefaultSavePathChanged 'true' + option CategorySavePathChanged 'true' + option Encryption '0' + option MaxRatioAction '0' + option CSRFProtection 'false' + option SeedChokingAlgorithm 'FastestUpload' + option Enabled 'false' + option Port '8080' + option profile '/opt' + option enabled '0' + diff --git a/package/lean/luci-app-qbittorrent/root/etc/init.d/qbittorrent b/package/lean/luci-app-qbittorrent/root/etc/init.d/qbittorrent index 383317165d..274aa45719 100755 --- a/package/lean/luci-app-qbittorrent/root/etc/init.d/qbittorrent +++ b/package/lean/luci-app-qbittorrent/root/etc/init.d/qbittorrent @@ -1,67 +1,264 @@ #!/bin/sh /etc/rc.common +# Licensed to the public under the Apache License 2.0. +# ubus call service list + START=99 -config_qbittorrent() -{ - local download_dir - local port - config_get download_dir $1 download_dir - config_get port $1 port - if [ -f $2/qBittorrent/config/qBittorrent.conf ]; then - sed -i 's/WebUI\\Port=[0-9]*/WebUI\\Port='"$port"'/g' $2/qBittorrent/config/qBittorrent.conf - sed -i 's/Downloads\\SavePath=[a-z,/]*//g' $2/qBittorrent/config/qBittorrent.conf - echo "Downloads\SavePath=$down" >> $2/qBittorrent/config/qBittorrent.conf - else - cat>$2/qBittorrent/config/qBittorrent.conf<"$QBT_INI_FILE"</dev/null 2>&1; + return 1; + } + + local confdir="qBittorrent" + [ -n "$configuration" ] && { + confdir="qBittorrent_$configuration" + } + + [ -d "$profile/$confdir/config" ] || { + mkdir -m 0755 -p "$profile/$confdir/config" + } + + [ "$user" != "root" ] && { + [ -d "$confdir" ] && { + local groupnow="$(ls -l $profile | grep $confdir | awk '{print $3})" + local usernow="$(ls -l $profile | grep $confdir | awk '{print $4})" + + [ "$usernow" != "$user" ] && { _err "Permission denied!"; return 1; } + } || { + chmod -R g+w "$profile/$confdir" + chown -R "$user":"$user" "$profile/$confdir" + } + } + + [ "$AuthSubnetWhitelistEnabled" = true ] && { + AuthSubnetWhitelist="$( echo $AuthSubnetWhitelist | sed 's/ /,/g')" + } || { + AuthSubnetWhitelist="@Invalid()" + } + + QBT_INI_FILE="$profile/$confdir/config/qBittorrent.conf" + config_QBT + + procd_open_instance $QBT_INSTANCE + procd_set_param command $args + procd_append_param command --profile="$profile" + + [ -n "$configuration" ] && { + procd_append_param command --configuration="$configuration" + } + + procd_set_param respawn + procd_set_param user $user + procd_set_param file $QBT_INI_FILE + procd_set_param pidfile $QBT_PID_FILE + procd_close_instance } -stop() +service_triggers() { - killall qbittorrent-nox - return 0 + procd_add_reload_trigger "$NAME" +} + +start_service() { + config_load "$NAME" + config_foreach init_QBT "$NAME" +} + +reload_service() { + restart +} + +restart() { + stop + sleep 2 + start } diff --git a/package/lean/luci-app-qbittorrent/root/etc/uci-defaults/luci-qbittorrent b/package/lean/luci-app-qbittorrent/root/etc/uci-defaults/luci-qbittorrent new file mode 100644 index 0000000000..dd2c37d8d8 --- /dev/null +++ b/package/lean/luci-app-qbittorrent/root/etc/uci-defaults/luci-qbittorrent @@ -0,0 +1,21 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@qbittorrent[-1] + add ucitrack qbittorrent + set ucitrack.@qbittorrent[-1].init=qbittorrent + commit ucitrack +EOF + +if [ ."$(uci -q get qbittorrent.main)" != ."qbittorrent" ]; then + uci -q batch <<-EOF >/dev/null + add qbittorrent qbittorrent + rename qbittorrent.@qbittorrent[-1]="main" + set qbittorrent.main.enabled=0 + set qbittorrent.main.profile="/tmp" + commit qbittorrent + EOF +fi + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/lean/luci-app-ssr-plus/Makefile b/package/lean/luci-app-ssr-plus/Makefile index 77fb0a6c17..2f66356c3a 100644 --- a/package/lean/luci-app-ssr-plus/Makefile +++ b/package/lean/luci-app-ssr-plus/Makefile @@ -2,10 +2,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-ssr-plus PKG_VERSION:=1 -PKG_RELEASE:=125 +PKG_RELEASE:=131 PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks @@ -21,6 +22,10 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray bool "Include V2ray" default y if x86_64 +config PACKAGE_$(PKG_NAME)_INCLUDE_Trojan + bool "Include Trojan" + default y if x86_64 + config PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun bool "Include Kcptun" default n @@ -43,6 +48,8 @@ define Package/luci-app-ssr-plus DEPENDS:=+shadowsocksr-libev-alt +ipset +ip-full +iptables-mod-tproxy +dnsmasq-full +coreutils +coreutils-base64 +bash +pdnsd-alt +wget \ +PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \ +PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray \ + +PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:trojan \ + +PACKAGE_$(PKG_NAME)_INCLUDE_Trojan:ipt2socks \ +PACKAGE_$(PKG_NAME)_INCLUDE_Kcptun:openwrt-kcptun-client \ +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server:shadowsocksr-libev-server \ +PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Socks:shadowsocksr-libev-ssr-local diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua index 5b7dc7fe32..abe8cf90ca 100644 --- a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua @@ -114,7 +114,7 @@ s = m:section(NamedSection, sid, "servers") s.anonymous = true s.addremove = false -o = s:option(DummyValue,"ssr_url","SS/SSR/V2RAY URL") +o = s:option(DummyValue,"ssr_url","SS/SSR/V2RAY/TROJAN URL") o.rawhtml = true o.template = "shadowsocksr/ssrurl" o.value =sid @@ -127,6 +127,9 @@ end if nixio.fs.access("/usr/bin/v2ray/v2ray") then o:value("v2ray", translate("V2Ray")) end +if nixio.fs.access("/usr/sbin/trojan") then +o:value("trojan", translate("Trojan")) +end o.description = translate("Using incorrect encryption mothod may causes service fail to start") o = s:option(Value, "alias", translate("Alias(optional)")) @@ -149,6 +152,7 @@ o.password = true o.rmempty = true o:depends("type", "ssr") o:depends("type", "ss") +o:depends("type", "trojan") o = s:option(ListValue, "encrypt_method", translate("Encrypt Method")) for _, v in ipairs(encrypt_methods) do o:value(v) end @@ -327,18 +331,26 @@ o.rmempty = true o = s:option(Flag, "insecure", translate("allowInsecure")) o.rmempty = true o:depends("type", "v2ray") +o:depends("type", "trojan") -- [[ TLS ]]-- o = s:option(Flag, "tls", translate("TLS")) o.rmempty = true o.default = "0" o:depends("type", "v2ray") +o:depends("type", "trojan") + +o = s:option(Value, "tls_host", translate("TLS Host")) +o:depends("tls", "1") +o.rmempty = true +o:depends("type", "trojan") -- [[ Mux ]]-- o = s:option(Flag, "mux", translate("Mux")) o.rmempty = true o.default = "0" o:depends("type", "v2ray") +o:depends("type", "trojan") o = s:option(Value, "concurrency", translate("Concurrency")) o.datatype = "uinteger" diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua index 05b4162fc4..914e7e1f62 100644 --- a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/log.lua @@ -2,7 +2,8 @@ local fs = require "nixio.fs" local conffile = "/tmp/ssrpro.log" f = SimpleForm("logview") - +f.reset = false +f.submit = false t = f:field(TextValue, "conf") t.rmempty = true t.rows = 20 @@ -12,4 +13,4 @@ function t.cfgvalue() end t.readonly="readonly" -return f \ No newline at end of file +return f diff --git a/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm index 639ef70271..bc7f287172 100644 --- a/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm +++ b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm @@ -88,7 +88,7 @@ var s = document.getElementById(urlname + '-status'); if (!s) return false; - var ssrurl = prompt("在这里黏贴配置链接 ssr:// | ss:// | vmess://", ""); + var ssrurl = prompt("在这里黏贴配置链接 ssr:// | ss:// | vmess:// | trojan://", ""); if (ssrurl == null || ssrurl == "") { s.innerHTML = "用户取消"; return false; @@ -97,7 +97,7 @@ //var ssu = ssrurl.match(/ssr:\/\/([A-Za-z0-9_-]+)/i); var ssu = ssrurl.split('://'); console.log(ssu.length); - if ((ssu[0] != "ssr" && ssu[0] != "ss" && ssu[0] != "vmess") || ssu[1] == "") { + if ((ssu[0] != "ssr" && ssu[0] != "ss" && ssu[0] != "vmess" && ssu[0] != "trojan") || ssu[1] == "") { s.innerHTML = "无效格式"; return false; } @@ -170,6 +170,29 @@ s.innerHTML = "导入Shadowsocks配置信息成功"; return false; + } else if (ssu[0] == "trojan") { + var ploc = ssu[1].indexOf("#"); + if (ploc > 0) { + url0 = ssu[1].substr(0, ploc); + param = ssu[1].substr(ploc + 1); + } else { + url0 = ssu[1] + } + var sstr = b64decsafe(url0); + document.getElementById('cbid.shadowsocksr.' + sid + '.type').value = "trojan"; + document.getElementById('cbid.shadowsocksr.' + sid + '.type').dispatchEvent(event); + var team = sstr.split('@'); + console.log(param); + var part1 = team[0].split(':'); + var part2 = team[1].split(':'); + document.getElementById('cbid.shadowsocksr.' + sid + '.server').value = part2[0]; + document.getElementById('cbid.shadowsocksr.' + sid + '.server_port').value = part2[1]; + document.getElementById('cbid.shadowsocksr.' + sid + '.password').value = part1[1]; + if (param != undefined) { + document.getElementById('cbid.shadowsocksr.' + sid + '.alias').value = decodeURI(param); + } + s.innerHTML = "导入Trojan配置信息成功"; + return false; } else if (ssu[0] == "vmess") { var sstr = b64DecodeUnicode(ssu[1]); var ploc = sstr.indexOf("/?"); diff --git a/package/lean/luci-app-ssr-plus/po/zh-cn/ssr-plus.po b/package/lean/luci-app-ssr-plus/po/zh-cn/ssr-plus.po index 7f92a7f6dc..e028dcb7b0 100644 --- a/package/lean/luci-app-ssr-plus/po/zh-cn/ssr-plus.po +++ b/package/lean/luci-app-ssr-plus/po/zh-cn/ssr-plus.po @@ -378,7 +378,7 @@ msgid "GFW List" msgstr "GFW列表" msgid "ShadowSocksR Plus+ Settings" -msgstr "ShadowSocksR Plus+ 设置(支持SS/SSR/V2RAY)" +msgstr "ShadowSocksR Plus+ 设置(支持SS/SSR/V2RAY/TROJAN)" msgid "Main Server" msgstr "主服务器" @@ -516,10 +516,10 @@ msgid "Ping Latency" msgstr "Ping延迟" msgid "Bypass Domain List" -msgstr "域名白名单" +msgstr "不走代理的域名" msgid "Black Domain List" -msgstr "域名黑名单" +msgstr "强制走代理的域名" msgid "Update Subscribe List" msgstr "更新订阅URL列表" diff --git a/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr b/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr index c66d1f9d5a..783b1ff24b 100755 --- a/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr +++ b/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr @@ -43,11 +43,10 @@ uci_get_by_type() { add_cron() { - sed -i '/ssrplus.log/d' $CRON_FILE - echo '0 1 * * * echo "" > /tmp/ssrplus.log' >> $CRON_FILE - [ -n "$(grep -w "/usr/share/shadowsocksr/subscribe.sh" $CRON_FILE)" ] && sed -i '/\/usr\/share\/shadowsocksr\/subscribe.sh/d' $CRON_FILE + sed -i '/shadowsocksr/d' $CRON_FILE + sed -i '/ssrplus.log/d' $CRON_FILE && echo '0 1 * * * echo "" > /tmp/ssrplus.log' >> $CRON_FILE [ $(uci_get_by_type server_subscribe auto_update 0) -eq 1 ] && echo "0 $(uci_get_by_type server_subscribe auto_update_time) * * * /usr/share/shadowsocksr/subscribe.sh" >> $CRON_FILE - [ -z "$(grep -w "/usr/share/shadowsocksr/update.sh" $CRON_FILE)" ] && echo "0 5 * * * /usr/share/shadowsocksr/update.sh" >> $CRON_FILE + [ $(uci_get_by_type server_subscribe auto_update 0) -eq 1 ] && echo "0 5 * * * /usr/share/shadowsocksr/update.sh" >> $CRON_FILE crontab $CRON_FILE } @@ -67,7 +66,7 @@ gen_config_file() { elif [ "$host" != "${host#*:[0-9a-fA-F]}" ] ;then hostip=${host} else - hostip=`nslookup ${host} | grep 'Address 1' | sed 's/Address 1: //g'` + hostip=`ping ${host} -s 1 -c 1 | grep PING | cut -d'(' -f 2 | cut -d')' -f1` if echo $hostip|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then hostip=${hostip} else @@ -125,6 +124,9 @@ EOF elif [ "$stype" == "v2ray" ] ;then lua /usr/share/shadowsocksr/genv2config.lua $GLOBAL_SERVER tcp $(uci_get_by_name $1 local_port) > /var/etc/v2-ssr-retcp.json sed -i 's/\\//g' /var/etc/v2-ssr-retcp.json + elif [ "$stype" == "trojan" ] ;then + lua /usr/share/shadowsocksr/gentrojanconfig.lua $GLOBAL_SERVER nat $(uci_get_by_name $1 local_port) > /var/etc/trojan-ssr-retcp.json + sed -i 's/\\//g' /var/etc/trojan-ssr-retcp.json fi } @@ -143,7 +145,7 @@ start_rules() { elif [ "$server" != "${server#*:[0-9a-fA-F]}" ] ;then server=${server} else - server=`nslookup ${server} | grep 'Address 1' | sed 's/Address 1: //g'` + server=`ping ${server} -s 1 -c 1 | grep PING | cut -d'(' -f 2 | cut -d')' -f1` if echo $server|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then echo $server >/etc/ssr_ip else @@ -265,7 +267,7 @@ server { } EOF - /usr/sbin/pdnsd -c /var/etc/pdnsd.conf & + /usr/sbin/pdnsd -c /var/etc/pdnsd.conf -d } @@ -301,6 +303,8 @@ start_redir() { sscmd="/usr/bin/ssr-redir" elif [ "$stype" == "v2ray" ] ;then sscmd="/usr/bin/v2ray/v2ray" + elif [ "$stype" == "trojan" ] ;then + sscmd="/usr/sbin/trojan" fi local utype=$(uci_get_by_name $UDP_RELAY_SERVER type) @@ -310,6 +314,8 @@ start_redir() { ucmd="/usr/bin/ssr-redir" elif [ "$utype" == "v2ray" ] ;then ucmd="/usr/bin/v2ray/v2ray" + elif [ "$utype" == "trojan" ] ;then + ucmd="/usr/sbin/trojan" fi if [ "$(uci_get_by_type global threads 0)" = "0" ] ;then @@ -330,6 +336,9 @@ start_redir() { elif [ "$stype" == "v2ray" ] ;then $sscmd -config /var/etc/v2-ssr-retcp.json >/dev/null 2>&1 & echo "$(date "+%Y-%m-%d %H:%M:%S") $($sscmd -version | head -1) Started!" >> /tmp/ssrplus.log + elif [ "$stype" == "trojan" ] ;then + $sscmd --config /var/etc/trojan-ssr-retcp.json >/dev/null 2>&1 & + echo "$(date "+%Y-%m-%d %H:%M:%S") $($sscmd --version 2>&1 | head -1) Started!" >> /tmp/ssrplus.log fi if [ -n "$UDP_RELAY_SERVER" ] ;then @@ -346,7 +355,12 @@ start_redir() { elif [ "$utype" == "v2ray" ] ; then lua /usr/share/shadowsocksr/genv2config.lua $UDP_RELAY_SERVER udp $(uci_get_by_name $UDP_RELAY_SERVER local_port) > /var/etc/v2-ssr-reudp.json sed -i 's/\\//g' /var/etc/v2-ssr-reudp.json - $ucmd -config /var/etc/v2-ssr-reudp.json >/dev/null 2>&1 & + $ucmd -config /var/etc/v2-ssr-reudp.json >/dev/null 2>&1 & + elif [ "$stype" == "trojan" ] ;then + lua /usr/share/shadowsocksr/gentrojanconfig.lua $GLOBAL_SERVER client 10801 > /var/etc/trojan-ssr-reudp.json + sed -i 's/\\//g' /var/etc/trojan-ssr-reudp.json + $ucmd --config /var/etc/trojan-ssr-reudp.json >/dev/null 2>&1 & + ipt2socks -U -4 -b 0.0.0.0 -s 127.0.0.1 -p 10801 -l $(uci_get_by_name $UDP_RELAY_SERVER local_port) >/dev/null 2>&1 & fi fi @@ -537,10 +551,16 @@ stop() { killall -q -9 ss-redir killall -q -9 ssr-redir killall -q -9 v2ray + killall -q -9 trojan + killall -q -9 ipt2socks killall -q -9 ssr-server killall -q -9 kcptun-client killall -q -9 ssr-local - killall -q -9 pdnsd + if [ -f /var/run/pdnsd.pid ] ;then + kill $(cat /var/run/pdnsd.pid) >/dev/null 2>&1 + else + kill -9 $(busybox ps -w | grep pdnsd | grep -v grep | awk '{print $1}') >/dev/null 2>&1 + fi if [ -f "/tmp/dnsmasq.d/dnsmasq-ssr.conf" ]; then rm -f /tmp/dnsmasq.d/dnsmasq-ssr.conf diff --git a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/gentrojanconfig.lua b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/gentrojanconfig.lua new file mode 100644 index 0000000000..9d85bc41d0 --- /dev/null +++ b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/gentrojanconfig.lua @@ -0,0 +1,38 @@ +local ucursor = require "luci.model.uci".cursor() +local json = require "luci.jsonc" +local server_section = arg[1] +local proto = arg[2] +local local_port = arg[3] + +local server = ucursor:get_all("shadowsocksr", server_section) + +local trojan = { + log_level = 3, + run_type = proto, + local_addr = "0.0.0.0", + local_port = tonumber(local_port), + remote_addr = server.server, + remote_port = tonumber(server.server_port), + udp_timeout = 60, + -- 传入连接 + password = {server.password}, + -- 传出连接 + ssl = { + verify = false, + verify_hostname = (server.tls == "1") and false or true, + cert = "", + ciper = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:RSA-AES128-GCM-SHA256:RSA-AES256-GCM-SHA384:RSA-AES128-SHA:RSA-AES256-SHA:RSA-3DES-EDE-SHA", + sni = server.tls_host, + alpn = {"h2", "http/1.1"}, + curve = "", + reuse_session = true, + session_ticket = false, + }, + tcp = { + no_delay = true, + keep_alive = true, + fast_open = (server.fast_open == "1") and true or false, + fast_open_qlen = 20 + } +} +print(json.stringify(trojan, 1)) diff --git a/package/lean/luci-app-unblockmusic/Makefile b/package/lean/luci-app-unblockmusic/Makefile index a50de73a3b..f8cdfe9c74 100644 --- a/package/lean/luci-app-unblockmusic/Makefile +++ b/package/lean/luci-app-unblockmusic/Makefile @@ -11,7 +11,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-unblockmusic PKG_VERSION:=2.2.0 -PKG_RELEASE:=9 +PKG_RELEASE:=11 PKG_LICENSE:=Apache-2.0 diff --git a/package/lean/luci-app-unblockmusic/root/etc/init.d/unblockmusic b/package/lean/luci-app-unblockmusic/root/etc/init.d/unblockmusic index 5be5239562..9ff4963a2f 100755 --- a/package/lean/luci-app-unblockmusic/root/etc/init.d/unblockmusic +++ b/package/lean/luci-app-unblockmusic/root/etc/init.d/unblockmusic @@ -25,7 +25,7 @@ add_rule() $ipt_n -A cloud_music -d 192.168.0.0/16 -j RETURN $ipt_n -A cloud_music -d 224.0.0.0/4 -j RETURN $ipt_n -A cloud_music -d 240.0.0.0/4 -j RETURN - $ipt_n -A cloud_music -p tcp -j REDIRECT --to-ports 5202 + $ipt_n -A cloud_music -p tcp -j REDIRECT --to-ports 5200 $ipt_n -I PREROUTING -p tcp --dport 80 -m set --match-set music dst -j cloud_music } @@ -41,7 +41,7 @@ del_rule(){ set_firewall(){ rm -f /tmp/dnsmasq.d/dnsmasq-163.conf mkdir -p /tmp/dnsmasq.d - echo "dhcp-option=252,http://$ROUTE_IP:5200/proxy.pac" > /tmp/dnsmasq.d/dnsmasq-163.conf + echo "dhcp-option=252,http://$ROUTE_IP:5201/proxy.pac" > /tmp/dnsmasq.d/dnsmasq-163.conf echo "ipset=/music.163.com/music" >> /tmp/dnsmasq.d/dnsmasq-163.conf echo "ipset=/interface.music.163.com/music" >> /tmp/dnsmasq.d/dnsmasq-163.conf /etc/init.d/dnsmasq restart >/dev/null 2>&1 @@ -82,11 +82,11 @@ start() fi if [ $TYPE = "default" ]; then - node /usr/share/UnblockNeteaseMusic/app.js $endponintset -p 5200:5201 >/tmp/unblockmusic.log 2>&1 & - node /usr/share/UnblockNeteaseMusic/app.js -p 5202 >>/tmp/unblockmusic.log 2>&1 & + node /usr/share/UnblockNeteaseMusic/app.js $endponintset -p 5201:5202 >/tmp/unblockmusic.log 2>&1 & + node /usr/share/UnblockNeteaseMusic/app.js -p 5200 >>/tmp/unblockmusic.log 2>&1 & else - node /usr/share/UnblockNeteaseMusic/app.js $endponintset -p 5200:5201 -o $TYPE >/tmp/unblockmusic.log 2>&1 & - node /usr/share/UnblockNeteaseMusic/app.js -p 5202 -o $TYPE >>/tmp/unblockmusic.log 2>&1 & + node /usr/share/UnblockNeteaseMusic/app.js $endponintset -p 5201:5202 -o $TYPE >/tmp/unblockmusic.log 2>&1 & + node /usr/share/UnblockNeteaseMusic/app.js -p 5200 -o $TYPE >>/tmp/unblockmusic.log 2>&1 & fi set_firewall diff --git a/package/lean/luci-app-unblockmusic/root/lib/upgrade/keep.d/unblockmusic b/package/lean/luci-app-unblockmusic/root/lib/upgrade/keep.d/unblockmusic new file mode 100644 index 0000000000..4f44321e28 --- /dev/null +++ b/package/lean/luci-app-unblockmusic/root/lib/upgrade/keep.d/unblockmusic @@ -0,0 +1,3 @@ +/usr/share/UnblockNeteaseMusic/ca.crt +/usr/share/UnblockNeteaseMusic/server.crt +/usr/share/UnblockNeteaseMusic/server.key \ No newline at end of file diff --git a/package/lean/luci-app-unblockmusic/root/usr/share/UnblockNeteaseMusic/logcheck.sh b/package/lean/luci-app-unblockmusic/root/usr/share/UnblockNeteaseMusic/logcheck.sh index 168020537d..4d8eb1001e 100755 --- a/package/lean/luci-app-unblockmusic/root/usr/share/UnblockNeteaseMusic/logcheck.sh +++ b/package/lean/luci-app-unblockmusic/root/usr/share/UnblockNeteaseMusic/logcheck.sh @@ -1,11 +1,11 @@ #!/bin/bash -log_max_size="10" #使用KB计算 +log_max_size="100" #使用KB计算 log_file="/tmp/unblockmusic.log" while true do - sleep 10s + sleep 30s icount=`busybox ps -w | grep app.js |grep -v grep| wc -l` if [ $icount -ne 2 ] ;then /etc/init.d/unblockmusic restart diff --git a/package/lean/luci-app-unblockmusic/root/usr/share/UnblockNeteaseMusic/update_core.sh b/package/lean/luci-app-unblockmusic/root/usr/share/UnblockNeteaseMusic/update_core.sh index 51705698b8..649c5ac603 100755 --- a/package/lean/luci-app-unblockmusic/root/usr/share/UnblockNeteaseMusic/update_core.sh +++ b/package/lean/luci-app-unblockmusic/root/usr/share/UnblockNeteaseMusic/update_core.sh @@ -10,7 +10,7 @@ function clean_log(){ } function check_latest_version(){ - latest_ver="$(wget -O- https://github.com/nondanee/UnblockNeteaseMusic/commits/master |tr -d '\n' |grep -Eo 'commit\/[0-9a-z]+' |sed -n 1p |sed 's#commit/##g')" + latest_ver="$(wget-ssl --no-check-certificate -O- https://github.com/nondanee/UnblockNeteaseMusic/commits/master |tr -d '\n' |grep -Eo 'commit\/[0-9a-z]+' |sed -n 1p |sed 's#commit/##g')" [ -z "${latest_ver}" ] && echo -e "\nFailed to check latest version, please try again later." >>/tmp/unblockmusic_update.log && exit 1 if [ ! -e "/usr/share/UnblockNeteaseMusic/local_ver" ]; then clean_log diff --git a/package/lean/qBittorrent/Makefile b/package/lean/qBittorrent/Makefile index 5e3650c6ea..3bd02e2658 100644 --- a/package/lean/qBittorrent/Makefile +++ b/package/lean/qBittorrent/Makefile @@ -1,14 +1,14 @@ include $(TOPDIR)/rules.mk -PKG_NAME:=qBittorrent -PKG_VERSION:=4.1.8 -PKG_RELEASE=1 +PKG_NAME:=qbittorrent +PKG_VERSION:=4.1.9 +PKG_RELEASE=5 -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://github.com/qbittorrent/qBittorrent.git -PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) -PKG_SOURCE_VERSION:=0de5cbaa4becf4eb89245324cb76c9a7c9412a33 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE:=$(PKG_NAME)-release-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/qbittorrent/qBittorrent/tar.gz/release-$(PKG_VERSION)? +PKG_HASH:=620127f73f88ed3f2b2e4195cbc641f7c27f967d3b045e45f7916c0995fd61fe + +PKG_BUILD_DIR:=$(BUILD_DIR)/qBittorrent-release-$(PKG_VERSION) PKG_LICENSE:=GPL-2.0+ PKG_LICENSE_FILES:=COPYING @@ -36,17 +36,19 @@ there. qBittorrent is fast, stable and provides unicode support as well as many features. endef -CONFIGURE_VARS += \ - QT_QMAKE="$(TOOLCHAIN_DIR)/bin" \ - PKG_CONFIG_PATH="$(TOOLCHAIN_DIR)/lib/pkgconfig" - CONFIGURE_ARGS += \ --disable-gui \ + --enable-stacktrace=no \ --with-boost=$(STAGING_DIR)/usr MAKE_VARS += \ INSTALL_ROOT="$(PKG_INSTALL_DIR)" +define Build/Prepare + $(call Build/Prepare/Default) + $(SED) '//{:a;N;/<\/context>/!ba;/\/gui\//d}' `ls $(PKG_BUILD_DIR)/src/lang/qbittorrent_*.ts` +endef + define Package/qBittorrent/install $(INSTALL_DIR) $(1)/usr/man/man1 $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/man/man1/qbittorrent-nox.1 $(1)/usr/man/man1/qbittorrent-nox.1 diff --git a/package/lean/qBittorrent/patches/001-remove-ico-not-for-webui.patch b/package/lean/qBittorrent/patches/001-remove-ico-not-for-webui.patch new file mode 100644 index 0000000000..ee27bbaca4 --- /dev/null +++ b/package/lean/qBittorrent/patches/001-remove-ico-not-for-webui.patch @@ -0,0 +1,126 @@ +--- a/src/icons/icons.qrc ++++ b/src/icons/icons.qrc +@@ -250,38 +250,16 @@ + flags/zm.svg + flags/zw.svg + L.gif +- loading.png + qbt-theme/application-exit.svg +- qbt-theme/application-rss+xml.svg +- qbt-theme/application-x-mswinurl.svg + qbt-theme/checked.svg + qbt-theme/configure.svg +- qbt-theme/dialog-cancel.svg +- qbt-theme/dialog-information.svg +- qbt-theme/dialog-warning.svg + qbt-theme/document-edit-verify.svg + qbt-theme/document-edit.svg +- qbt-theme/document-encrypt.svg +- qbt-theme/document-import.svg +- qbt-theme/document-new.svg +- qbt-theme/document-properties.svg +- qbt-theme/document-save.svg +- qbt-theme/download.svg +- qbt-theme/edit-clear-history.svg + qbt-theme/edit-clear.svg + qbt-theme/edit-copy.svg +- qbt-theme/edit-cut.svg + qbt-theme/edit-delete.svg +- qbt-theme/edit-find-user.svg + qbt-theme/edit-find.svg +- qbt-theme/edit-paste.svg + qbt-theme/edit-rename.svg +- qbt-theme/folder-documents.svg +- qbt-theme/folder-download.svg +- qbt-theme/folder-new.svg +- qbt-theme/folder-remote.svg +- qbt-theme/gear.svg +- qbt-theme/gear32.svg + qbt-theme/go-bottom.svg + qbt-theme/go-down.svg + qbt-theme/go-top.svg +@@ -295,43 +273,15 @@ + qbt-theme/kt-set-max-upload-speed.png + qbt-theme/list-add.svg + qbt-theme/list-remove.svg +- qbt-theme/mail-folder-inbox.svg +- qbt-theme/mail-mark-read.svg + qbt-theme/media-playback-pause.svg + qbt-theme/media-playback-start.svg + qbt-theme/media-seek-forward.svg +- qbt-theme/network-server.svg +- qbt-theme/network-wired.svg +- qbt-theme/object-locked.svg +- qbt-theme/office-chart-line.svg +- qbt-theme/preferences-desktop.svg +- qbt-theme/preferences-other.svg +- qbt-theme/preferences-system-network.svg +- qbt-theme/preferences-web-browser-cookies.svg +- qbt-theme/rss-config.png + qbt-theme/security-high.svg + qbt-theme/security-low.svg +- qbt-theme/services.svg +- qbt-theme/speedometer.svg + qbt-theme/system-log-out.svg +- qbt-theme/tab-close.svg +- qbt-theme/task-attention.svg +- qbt-theme/task-complete.png +- qbt-theme/task-ongoing.png +- qbt-theme/task-reject.png +- qbt-theme/text-plain.svg +- qbt-theme/tools-report-bug.svg +- qbt-theme/unavailable.svg +- qbt-theme/user-group-delete.svg +- qbt-theme/user-group-new.svg +- qbt-theme/view-calendar-journal.svg + qbt-theme/view-categories.svg +- qbt-theme/view-filter.svg +- qbt-theme/view-preview.svg +- qbt-theme/view-refresh.svg + qbt-theme/view-statistics.svg + qbt-theme/wallet-open.svg +- qbt-theme/webui.svg + skin/arrow-right.gif + skin/bg-dropdown.gif + skin/bg-handle-horizontal.gif +@@ -342,7 +292,6 @@ + skin/completed.svg + skin/connected.svg + skin/disconnected.svg +- skin/dock-tabs.gif + skin/download.svg + skin/downloading.svg + skin/error.svg +@@ -353,14 +302,11 @@ + skin/handle-icon-horizontal.gif + skin/handle-icon.gif + skin/knob.gif +- skin/logo-blank.gif + skin/logo.gif + skin/logo2.gif + skin/mascot.png + skin/paused.svg + skin/qbittorrent-tray.svg +- skin/qbittorrent-tray-dark.svg +- skin/qbittorrent-tray-light.svg + skin/qbittorrent32.png + skin/queued.svg + skin/ratio.svg +@@ -370,17 +316,12 @@ + skin/spacer.gif + skin/spinner-placeholder.gif + skin/spinner.gif +- skin/splash.png + skin/stalledDL.svg + skin/stalledUP.svg + skin/tabs.gif + skin/toolbox-divider.gif +- skin/toolbox-divider2.gif + skin/uploading.svg + slow.png + slow_off.png +- sphere.png +- sphere2.png +- url.png + + diff --git a/package/lean/qBittorrent/patches/002-add-autoban-function.patch b/package/lean/qBittorrent/patches/002-add-autoban-function.patch new file mode 100644 index 0000000000..8de0f1e47b --- /dev/null +++ b/package/lean/qBittorrent/patches/002-add-autoban-function.patch @@ -0,0 +1,807 @@ +--- a/src/base/bittorrent/peerinfo.cpp ++++ b/src/base/bittorrent/peerinfo.cpp +@@ -186,11 +186,26 @@ PeerAddress PeerInfo::address() const + m_nativeInfo.ip.port()); + } + ++int PeerInfo::port() const ++{ ++ return m_nativeInfo.ip.port(); ++} ++ + QString PeerInfo::client() const + { + return QString::fromStdString(m_nativeInfo.client); + } + ++QString PeerInfo::pid() const ++{ ++ return QString::fromStdString(m_nativeInfo.pid.to_string()); ++} ++ ++QString PeerInfo::pidtoclient() const ++{ ++ return QString::fromStdString(libt::identify_client(m_nativeInfo.pid)); ++} ++ + qreal PeerInfo::progress() const + { + return m_nativeInfo.progress; +--- a/src/base/bittorrent/peerinfo.h ++++ b/src/base/bittorrent/peerinfo.h +@@ -34,6 +34,7 @@ + #include + + #include ++#include + + namespace BitTorrent + { +@@ -85,7 +86,10 @@ namespace BitTorrent + bool isPlaintextEncrypted() const; + + PeerAddress address() const; ++ int port() const; + QString client() const; ++ QString pid() const; ++ QString pidtoclient() const; + qreal progress() const; + int payloadUpSpeed() const; + int payloadDownSpeed() const; +--- a/src/base/bittorrent/session.cpp ++++ b/src/base/bittorrent/session.cpp +@@ -69,6 +69,7 @@ + #endif + + #include "base/algorithm.h" ++#include "base/bittorrent/peerinfo.h" + #include "base/exceptions.h" + #include "base/global.h" + #include "base/logger.h" +@@ -335,6 +336,8 @@ Session::Session(QObject *parent) + , m_isAltGlobalSpeedLimitEnabled(BITTORRENT_SESSION_KEY("UseAlternativeGlobalSpeedLimit"), false) + , m_isBandwidthSchedulerEnabled(BITTORRENT_SESSION_KEY("BandwidthSchedulerEnabled"), false) + , m_saveResumeDataInterval(BITTORRENT_SESSION_KEY("SaveResumeDataInterval"), 60) ++ , m_autoBanUnknownPeer(BITTORRENT_SESSION_KEY("AutoBanUnknownPeer"), true) ++ , m_showTrackerAuthWindow(BITTORRENT_SESSION_KEY("ShowTrackerAuthWindow"), true) + , m_port(BITTORRENT_SESSION_KEY("Port"), 8999) + , m_useRandomPort(BITTORRENT_SESSION_KEY("UseRandomPort"), false) + , m_networkInterface(BITTORRENT_SESSION_KEY("Interface")) +@@ -502,6 +505,7 @@ Session::Session(QObject *parent) + libt::ip_filter filter; + processBannedIPs(filter); + m_nativeSession->set_ip_filter(filter); ++ loadOfflineFilter(); + } + + m_categories = map_cast(m_storedCategories); +@@ -518,6 +522,17 @@ Session::Session(QObject *parent) + connect(m_refreshTimer, &QTimer::timeout, this, &Session::refresh); + m_refreshTimer->start(); + ++ // Unban Timer ++ m_unbanTimer = new QTimer(this); ++ m_unbanTimer->setInterval(500); ++ connect(m_unbanTimer, &QTimer::timeout, this, &Session::processUnbanRequest); ++ ++ // Ban Timer ++ m_banTimer = new QTimer(this); ++ m_banTimer->setInterval(500); ++ connect(m_banTimer, &QTimer::timeout, this, &Session::autoBanBadClient); ++ m_banTimer->start(); ++ + m_statistics = new Statistics(this); + + updateSeedingLimitTimer(); +@@ -1077,6 +1092,7 @@ void Session::configure() + enableIPFilter(); + else + disableIPFilter(); ++ loadOfflineFilter(); + m_IPFilteringChanged = false; + } + +@@ -1905,6 +1921,95 @@ void Session::banIP(const QString &ip) + } + } + ++bool Session::checkAccessFlags(const QString &ip) ++{ ++ libt::ip_filter filter = m_nativeSession->get_ip_filter(); ++ boost::system::error_code ec; ++ libt::address addr = libt::address::from_string(ip.toLatin1().constData(), ec); ++ Q_ASSERT(!ec); ++ if (ec) return false; ++ return filter.access(addr); ++} ++ ++void Session::tempblockIP(const QString &ip) ++{ ++ libt::ip_filter filter = m_nativeSession->get_ip_filter(); ++ boost::system::error_code ec; ++ libt::address addr = libt::address::from_string(ip.toLatin1().constData(), ec); ++ Q_ASSERT(!ec); ++ if (ec) return; ++ filter.add_rule(addr, addr, libt::ip_filter::blocked); ++ m_nativeSession->set_ip_filter(filter); ++ insertQueue(ip); ++} ++ ++void Session::removeBlockedIP(const QString &ip) ++{ ++ libt::ip_filter filter = m_nativeSession->get_ip_filter(); ++ boost::system::error_code ec; ++ libt::address addr = libt::address::from_string(ip.toLatin1().constData(), ec); ++ Q_ASSERT(!ec); ++ if (ec) return; ++ filter.add_rule(addr, addr, 0); ++ m_nativeSession->set_ip_filter(filter); ++} ++ ++void Session::eraseIPFilter() ++{ ++ q_bannedIPs.clear(); ++ q_unbanTime.clear(); ++ if (isIPFilteringEnabled()) { ++ enableIPFilter(); ++ } else { ++ disableIPFilter(); ++ loadOfflineFilter(); ++ } ++} ++ ++void Session::autoBanBadClient() ++{ ++ const BitTorrent::SessionStatus tStatus = BitTorrent::Session::instance()->status(); ++ if (tStatus.peersCount > 0) { ++ bool m_AutoBan = BitTorrent::Session::instance()->isAutoBanUnknownPeerEnabled(); ++ foreach (BitTorrent::TorrentHandle *const torrent, BitTorrent::Session::instance()->torrents()) { ++ QList peers = torrent->peers(); ++ foreach (const BitTorrent::PeerInfo &peer, peers) { ++ BitTorrent::PeerAddress addr = peer.address(); ++ if (addr.ip.isNull()) continue; ++ QString ip = addr.ip.toString(); ++ int port = peer.port(); ++ QString client = peer.client(); ++ QString ptoc = peer.pidtoclient(); ++ QString pid = peer.pid().left(8); ++ QString country = peer.country(); ++ ++ QRegExp IDFilter("-(XL|SD|XF|QD|BN|DL)(\\d+)-"); ++ QRegExp UAFilter("\\d+.\\d+.\\d+.\\d+"); ++ if (IDFilter.exactMatch(pid) || UAFilter.exactMatch(client)) { ++ qDebug("Auto Banning bad Peer %s...", ip.toLocal8Bit().data()); ++ Logger::instance()->addMessage(tr("Auto banning bad Peer '%1'...'%2'...'%3'...'%4'").arg(ip).arg(pid).arg(ptoc).arg(country)); ++ tempblockIP(ip); ++ continue; ++ } ++ ++ if(m_AutoBan) { ++ if (client.contains("Unknown") && country == "CN") { ++ qDebug("Auto Banning Unknown Peer %s...", ip.toLocal8Bit().data()); ++ Logger::instance()->addMessage(tr("Auto banning Unknown Peer '%1'...'%2'...'%3'...'%4'").arg(ip).arg(pid).arg(ptoc).arg(country)); ++ tempblockIP(ip); ++ continue; ++ } ++ if (port >= 65000 && country == "CN" && client.contains("Transmission")) { ++ qDebug("Auto Banning Offline Downloader %s...", ip.toLocal8Bit().data()); ++ Logger::instance()->addMessage(tr("Auto banning Offline Downloader '%1:%2'...'%3'...'%4'...'%5'").arg(ip).arg(port).arg(pid).arg(ptoc).arg(country)); ++ tempblockIP(ip); ++ } ++ } ++ } ++ } ++ } ++} ++ + // Delete a torrent from the session, given its hash + // deleteLocalFiles = true means that the torrent will be removed from the hard-drive too + bool Session::deleteTorrent(const QString &hash, bool deleteLocalFiles) +@@ -2787,6 +2892,30 @@ void Session::setSaveResumeDataInterval( + } + } + ++bool Session::isAutoBanUnknownPeerEnabled() const ++{ ++ return m_autoBanUnknownPeer; ++} ++ ++void Session::setAutoBanUnknownPeer(bool value) ++{ ++ if (value != isAutoBanUnknownPeerEnabled()) { ++ m_autoBanUnknownPeer = value; ++ } ++} ++ ++bool Session::isShowTrackerAuthWindow() const ++{ ++ return m_showTrackerAuthWindow; ++} ++ ++void Session::setShowTrackerAuthWindow(bool value) ++{ ++ if (value != isShowTrackerAuthWindow()) { ++ m_showTrackerAuthWindow = value; ++ } ++} ++ + int Session::port() const + { + static int randomPort = Utils::Random::rand(1024, 65535); +@@ -3877,6 +4006,220 @@ void Session::disableIPFilter() + m_nativeSession->set_ip_filter(filter); + } + ++// Insert banned IP to Queue ++void Session::insertQueue(QString ip) ++{ ++ q_bannedIPs.enqueue(ip); ++ q_unbanTime.enqueue(QDateTime::currentMSecsSinceEpoch() + 60 * 60 * 1000); ++ ++ if (!m_unbanTimer->isActive()) { ++ m_unbanTimer->start(); ++ } ++} ++ ++// Process Unban Queue ++void Session::processUnbanRequest() ++{ ++ if (q_bannedIPs.isEmpty() && q_unbanTime.isEmpty()) { ++ m_unbanTimer->stop(); ++ } ++ else if (m_isActive) { ++ return; ++ } ++ else { ++ m_isActive = true; ++ int64_t currentTime = QDateTime::currentMSecsSinceEpoch(); ++ int64_t nextTime = q_unbanTime.dequeue(); ++ int delayTime = int(nextTime - currentTime); ++ QString nextIP = q_bannedIPs.dequeue(); ++ if (delayTime < 0) { ++ QTimer::singleShot(0, [=] { BitTorrent::Session::instance()->removeBlockedIP(nextIP); m_isActive = false; }); ++ } ++ else { ++ QTimer::singleShot(delayTime, [=] { BitTorrent::Session::instance()->removeBlockedIP(nextIP); m_isActive = false; }); ++ } ++ } ++} ++ ++// Handle ipfilter.dat ++int trim(char* const data, int start, int end) ++{ ++ if (start >= end) return start; ++ int newStart = start; ++ ++ for (int i = start; i <= end; ++i) { ++ if (isspace(data[i]) != 0) { ++ data[i] = '\0'; ++ } ++ else { ++ newStart = i; ++ break; ++ } ++ } ++ ++ for (int i = end; i >= start; --i) { ++ if (isspace(data[i]) != 0) ++ data[i] = '\0'; ++ else ++ break; ++ } ++ ++ return newStart; ++} ++ ++int findAndNullDelimiter(char *const data, char delimiter, int start, int end) ++{ ++ for (int i = start; i <= end; ++i) { ++ if (data[i] == delimiter) { ++ data[i] = '\0'; ++ return i; ++ } ++ } ++ ++ return -1; ++} ++ ++int Session::parseOfflineFilterFile(QString ipDat, libt::ip_filter &filter) ++{ ++ int ruleCount = 0; ++ QFile file(ipDat); ++ if (!file.exists()) return ruleCount; ++ ++ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { ++ LogMsg(tr("I/O Error: Could not open IP filter file in read mode."), Log::CRITICAL); ++ return ruleCount; ++ } ++ ++ std::vector buffer(2 * 1024 * 1024, 0); // seems a bit faster than QVector ++ qint64 bytesRead = 0; ++ int offset = 0; ++ int start = 0; ++ int endOfLine = -1; ++ int nbLine = 0; ++ ++ while (true) { ++ bytesRead = file.read(buffer.data() + offset, 2 * 1024 * 1024 - offset - 1); ++ if (bytesRead < 0) ++ break; ++ int dataSize = bytesRead + offset; ++ if (bytesRead == 0 && dataSize == 0) ++ break; ++ ++ for (start = 0; start < dataSize; ++start) { ++ endOfLine = -1; ++ // The file might have ended without the last line having a newline ++ if (!(bytesRead == 0 && dataSize > 0)) { ++ for (int i = start; i < dataSize; ++i) { ++ if (buffer[i] == '\n') { ++ endOfLine = i; ++ // We need to NULL the newline in case the line has only an IP range. ++ // In that case the parser won't work for the end IP, because it ends ++ // with the newline and not with a number. ++ buffer[i] = '\0'; ++ break; ++ } ++ } ++ } ++ else { ++ endOfLine = dataSize; ++ buffer[dataSize] = '\0'; ++ } ++ ++ if (endOfLine == -1) { ++ // read the next chunk from file ++ // but first move(copy) the leftover data to the front of the buffer ++ offset = dataSize - start; ++ memmove(buffer.data(), buffer.data() + start, offset); ++ break; ++ } ++ else { ++ ++nbLine; ++ } ++ ++ if ((buffer[start] == '#') ++ || ((buffer[start] == '/') && ((start + 1 < dataSize) && (buffer[start + 1] == '/')))) { ++ start = endOfLine; ++ continue; ++ } ++ ++ // Each line should follow this format: ++ // 001.009.096.105 - 001.009.096.105 , 000 , Some organization ++ // The 3rd entry is access level and if above 127 the IP range isn't blocked. ++ int firstComma = findAndNullDelimiter(buffer.data(), ',', start, endOfLine); ++ if (firstComma != -1) ++ findAndNullDelimiter(buffer.data(), ',', firstComma + 1, endOfLine); ++ ++ // Check if there is an access value (apparently not mandatory) ++ if (firstComma != -1) { ++ // There is possibly one ++ const long int nbAccess = strtol(buffer.data() + firstComma + 1, nullptr, 10); ++ // Ignoring this rule because access value is too high ++ if (nbAccess > 127L) { ++ start = endOfLine; ++ continue; ++ } ++ } ++ ++ // IP Range should be split by a dash ++ int endOfIPRange = ((firstComma == -1) ? (endOfLine - 1) : (firstComma - 1)); ++ int delimIP = findAndNullDelimiter(buffer.data(), '-', start, endOfIPRange); ++ if (delimIP == -1) { ++ start = endOfLine; ++ continue; ++ } ++ ++ boost::system::error_code ec; ++ int newStart = trim(buffer.data(), start, delimIP - 1); ++ libt::address startAddr = libt::address::from_string(buffer.data() + newStart, ec); ++ Q_ASSERT(!ec); ++ if (ec) { ++ start = endOfLine; ++ continue; ++ } ++ ++ newStart = trim(buffer.data(), delimIP + 1, endOfIPRange); ++ libt::address endAddr = libt::address::from_string(buffer.data() + newStart, ec); ++ Q_ASSERT(!ec); ++ if (ec) { ++ start = endOfLine; ++ continue; ++ } ++ ++ if ((startAddr.is_v4() != endAddr.is_v4()) ++ || (startAddr.is_v6() != endAddr.is_v6())) { ++ start = endOfLine; ++ continue; ++ } ++ ++ start = endOfLine; ++ ++ filter.add_rule(startAddr, endAddr, libt::ip_filter::blocked); ++ ++ruleCount; ++ } ++ ++ if (start >= dataSize) ++ offset = 0; ++ } ++ ++ return ruleCount; ++} ++ ++void Session::loadOfflineFilter() { ++ int Count = 0; ++ libt::ip_filter offlineFilter = m_nativeSession->get_ip_filter(); ++ ++#if defined(Q_OS_WIN) ++ Count = parseOfflineFilterFile("./ipfilter.dat", offlineFilter); ++#endif ++ ++#if (defined(Q_OS_UNIX) && !defined(Q_OS_MAC)) ++ Count = parseOfflineFilterFile(QDir::home().absoluteFilePath(".config")+"/qBittorrent/ipfilter.dat", offlineFilter); ++#endif ++ ++ m_nativeSession->set_ip_filter(offlineFilter); ++ Logger::instance()->addMessage(tr("Successfully parsed the offline downloader IP filter: %1 rules were applied.", "%1 is a number").arg(Count)); ++} ++ + void Session::recursiveTorrentDownload(const InfoHash &hash) + { + TorrentHandle *const torrent = m_torrents.value(hash); +@@ -4063,6 +4406,7 @@ void Session::handleIPFilterParsed(int r + } + Logger::instance()->addMessage(tr("Successfully parsed the provided IP filter: %1 rules were applied.", "%1 is a number").arg(ruleCount)); + emit IPFilterParsed(false, ruleCount); ++ loadOfflineFilter(); + } + + void Session::handleIPFilterError() +--- a/src/base/bittorrent/session.h ++++ b/src/base/bittorrent/session.h +@@ -40,8 +40,10 @@ + #include + #include + #include ++#include + #include + #include ++#include + #include + #include + +@@ -341,6 +343,10 @@ namespace BitTorrent + + uint saveResumeDataInterval() const; + void setSaveResumeDataInterval(uint value); ++ bool isAutoBanUnknownPeerEnabled() const; ++ void setAutoBanUnknownPeer(bool value); ++ bool isShowTrackerAuthWindow() const; ++ void setShowTrackerAuthWindow(bool value); + int port() const; + void setPort(int port); + bool useRandomPort() const; +@@ -467,6 +473,19 @@ namespace BitTorrent + void setMaxRatioAction(MaxRatioAction act); + + void banIP(const QString &ip); ++ bool checkAccessFlags(const QString &ip); ++ void tempblockIP(const QString &ip); ++ void removeBlockedIP(const QString &ip); ++ void eraseIPFilter(); ++ void autoBanBadClient(); ++ ++ // Unban Timer ++ bool m_isActive = false; ++ QQueue q_bannedIPs; ++ QQueue q_unbanTime; ++ QTimer *m_unbanTimer; ++ QTimer *m_banTimer; ++ void insertQueue(QString ip); + + bool isKnownTorrent(const InfoHash &hash) const; + bool addTorrent(QString source, const AddTorrentParams ¶ms = AddTorrentParams()); +@@ -546,6 +565,9 @@ namespace BitTorrent + void tagAdded(const QString &tag); + void tagRemoved(const QString &tag); + ++ public slots: ++ void processUnbanRequest(); ++ + private slots: + void configureDeferred(); + void readAlerts(); +@@ -601,6 +623,8 @@ namespace BitTorrent + void populateAdditionalTrackers(); + void enableIPFilter(); + void disableIPFilter(); ++ int parseOfflineFilterFile(QString ipDat, libtorrent::ip_filter &filter); ++ void loadOfflineFilter(); + + bool addTorrent_impl(CreateTorrentParams params, const MagnetUri &magnetUri, + TorrentInfo torrentInfo = TorrentInfo(), +@@ -713,6 +737,8 @@ namespace BitTorrent + CachedSettingValue m_isAltGlobalSpeedLimitEnabled; + CachedSettingValue m_isBandwidthSchedulerEnabled; + CachedSettingValue m_saveResumeDataInterval; ++ CachedSettingValue m_autoBanUnknownPeer; ++ CachedSettingValue m_showTrackerAuthWindow; + CachedSettingValue m_port; + CachedSettingValue m_useRandomPort; + CachedSettingValue m_networkInterface; +--- a/src/base/bittorrent/torrenthandle.cpp ++++ b/src/base/bittorrent/torrenthandle.cpp +@@ -1561,7 +1561,8 @@ void TorrentHandle::handleTrackerErrorAl + m_trackerInfos[trackerUrl].lastMessage = message; + + if (p->status_code == 401) +- m_session->handleTorrentTrackerAuthenticationRequired(this, trackerUrl); ++ if (Preferences::instance()->getShowTrackerAuthWindow()) ++ m_session->handleTorrentTrackerAuthenticationRequired(this, trackerUrl); + + m_session->handleTorrentTrackerError(this, trackerUrl); + } +--- a/src/base/preferences.cpp ++++ b/src/base/preferences.cpp +@@ -1090,6 +1090,26 @@ void Preferences::setTrayIconStyle(TrayI + } + #endif + ++bool Preferences::getAutoBanUnknownPeer() const ++{ ++ return value("Preferences/Advanced/AutoBanUnknownPeer", false).toBool(); ++} ++ ++void Preferences::setAutoBanUnknownPeer(const bool checked) ++{ ++ setValue("Preferences/Advanced/AutoBanUnknownPeer", checked); ++} ++ ++bool Preferences::getShowTrackerAuthWindow() const ++{ ++ return value("Preferences/Advanced/ShowTrackerAuthWindow", true).toBool(); ++} ++ ++void Preferences::setShowTrackerAuthWindow(const bool checked) ++{ ++ setValue("Preferences/Advanced/ShowTrackerAuthWindow", checked); ++} ++ + // Stuff that don't appear in the Options GUI but are saved + // in the same file. + +--- a/src/base/preferences.h ++++ b/src/base/preferences.h +@@ -300,6 +300,10 @@ public: + TrayIcon::Style trayIconStyle() const; + void setTrayIconStyle(TrayIcon::Style style); + #endif // Q_OS_MAC ++ bool getAutoBanUnknownPeer() const; ++ void setAutoBanUnknownPeer(const bool checked); ++ bool getShowTrackerAuthWindow() const; ++ void setShowTrackerAuthWindow(const bool checked); + + // Stuff that don't appear in the Options GUI but are saved + // in the same file. +--- a/src/base/settingsstorage.cpp ++++ b/src/base/settingsstorage.cpp +@@ -91,6 +91,8 @@ namespace + {"BitTorrent/Session/InterfaceName", "Preferences/Connection/InterfaceName"}, + {"BitTorrent/Session/InterfaceAddress", "Preferences/Connection/InterfaceAddress"}, + {"BitTorrent/Session/SaveResumeDataInterval", "Preferences/Downloads/SaveResumeDataInterval"}, ++ {"BitTorrent/Session/AutoBanUnknownPeer", "Preferences/Advanced/AutoBanUnknownPeer"}, ++ {"BitTorrent/Session/ShowTrackerAuthWindow", "Preferences/Advanced/ShowTrackerAuthWindow"}, + {"BitTorrent/Session/Encryption", "Preferences/Bittorrent/Encryption"}, + {"BitTorrent/Session/ForceProxy", "Preferences/Connection/ProxyForce"}, + {"BitTorrent/Session/ProxyPeerConnections", "Preferences/Connection/ProxyPeerConnections"}, +--- a/src/gui/advancedsettings.cpp ++++ b/src/gui/advancedsettings.cpp +@@ -60,6 +60,8 @@ enum AdvSettingsRows + NETWORK_LISTEN_IPV6, + // behavior + SAVE_RESUME_DATA_INTERVAL, ++ CONFIRM_AUTO_BAN, ++ SHOW_TRACKER_AUTH_WINDOW, + CONFIRM_RECHECK_TORRENT, + RECHECK_COMPLETED, + #if defined(Q_OS_WIN) || defined(Q_OS_MAC) +@@ -215,6 +217,10 @@ void AdvancedSettings::saveAdvancedSetti + // Announce IP + QHostAddress addr(lineEditAnnounceIP.text().trimmed()); + session->setAnnounceIP(addr.isNull() ? "" : addr.toString()); ++ // Auto ban Unknown Peer ++ session->setAutoBanUnknownPeer(cb_auto_ban_unknown_peer.isChecked()); ++ // Show Tracker Authenticaion Window ++ session->setShowTrackerAuthWindow(cb_show_tracker_auth_window.isChecked()); + + // Program notification + MainWindow *const mainWindow = static_cast(QCoreApplication::instance())->mainWindow(); +@@ -465,6 +471,12 @@ void AdvancedSettings::loadAdvancedSetti + // Announce IP + lineEditAnnounceIP.setText(session->announceIP()); + addRow(ANNOUNCE_IP, tr("IP Address to report to trackers (requires restart)"), &lineEditAnnounceIP); ++ // Auto Ban Unknown Peer from China ++ cb_auto_ban_unknown_peer.setChecked(session->isAutoBanUnknownPeerEnabled()); ++ addRow(CONFIRM_AUTO_BAN, tr("Auto Ban Unknown Peer from China"), &cb_auto_ban_unknown_peer); ++ // Show Tracker Authenticaion Window ++ cb_show_tracker_auth_window.setChecked(session->isShowTrackerAuthWindow()); ++ addRow(SHOW_TRACKER_AUTH_WINDOW, tr("Show Tracker Authenticaion Window"), &cb_show_tracker_auth_window); + + // Program notifications + const MainWindow *const mainWindow = static_cast(QCoreApplication::instance())->mainWindow(); +--- a/src/gui/advancedsettings.h ++++ b/src/gui/advancedsettings.h +@@ -65,7 +65,8 @@ private: + QCheckBox checkBoxOsCache, checkBoxRecheckCompleted, checkBoxResolveCountries, checkBoxResolveHosts, checkBoxSuperSeeding, + checkBoxProgramNotifications, checkBoxTorrentAddedNotifications, checkBoxTrackerFavicon, checkBoxTrackerStatus, + checkBoxConfirmTorrentRecheck, checkBoxConfirmRemoveAllTags, checkBoxListenIPv6, checkBoxAnnounceAllTrackers, checkBoxAnnounceAllTiers, +- checkBoxGuidedReadCache, checkBoxMultiConnectionsPerIp, checkBoxSuggestMode, checkBoxCoalesceRW, checkBoxSpeedWidgetEnabled; ++ checkBoxGuidedReadCache, checkBoxMultiConnectionsPerIp, checkBoxSuggestMode, checkBoxCoalesceRW, checkBoxSpeedWidgetEnabled, ++ cb_auto_ban_unknown_peer, cb_show_tracker_auth_window; + QComboBox comboBoxInterface, comboBoxInterfaceAddress, comboBoxUtpMixedMode, comboBoxChokingAlgorithm, comboBoxSeedChokingAlgorithm; + QLineEdit lineEditAnnounceIP; + +--- a/src/gui/mainwindow.cpp ++++ b/src/gui/mainwindow.cpp +@@ -73,6 +73,7 @@ + #include "addnewtorrentdialog.h" + #include "application.h" + #include "autoexpandabledialog.h" ++#include "base/bittorrent/peerinfo.h" + #include "cookiesdialog.h" + #include "downloadfromurldialog.h" + #include "executionlogwidget.h" +--- a/src/gui/properties/peerlistdelegate.h ++++ b/src/gui/properties/peerlistdelegate.h +@@ -49,6 +49,7 @@ public: + CONNECTION, + FLAGS, + CLIENT, ++ PEERID, + PROGRESS, + DOWN_SPEED, + UP_SPEED, +--- a/src/gui/properties/peerlistwidget.cpp ++++ b/src/gui/properties/peerlistwidget.cpp +@@ -75,6 +75,7 @@ PeerListWidget::PeerListWidget(Propertie + m_listModel->setHeaderData(PeerListDelegate::FLAGS, Qt::Horizontal, tr("Flags")); + m_listModel->setHeaderData(PeerListDelegate::CONNECTION, Qt::Horizontal, tr("Connection")); + m_listModel->setHeaderData(PeerListDelegate::CLIENT, Qt::Horizontal, tr("Client", "i.e.: Client application")); ++ m_listModel->setHeaderData(PeerListDelegate::PEERID, Qt::Horizontal, tr("Peer ID", "i.e.: Client Peer ID")); + m_listModel->setHeaderData(PeerListDelegate::PROGRESS, Qt::Horizontal, tr("Progress", "i.e: % downloaded")); + m_listModel->setHeaderData(PeerListDelegate::DOWN_SPEED, Qt::Horizontal, tr("Down Speed", "i.e: Download speed")); + m_listModel->setHeaderData(PeerListDelegate::UP_SPEED, Qt::Horizontal, tr("Up Speed", "i.e: Upload speed")); +@@ -288,8 +289,13 @@ void PeerListWidget::banSelectedPeers() + for (const QModelIndex &index : selectedIndexes) { + int row = m_proxyModel->mapToSource(index).row(); + QString ip = m_listModel->data(m_listModel->index(row, PeerListDelegate::IP_HIDDEN)).toString(); ++ QString client = m_listModel->data(m_listModel->index(row, PeerListDelegate::CLIENT)).toString(); ++ QString peerid = m_listModel->data(m_listModel->index(row, PeerListDelegate::PEERID)).toString(); ++ QHostAddress host; ++ host.setAddress(ip); ++ const QString countryName = Net::GeoIPManager::CountryName(Net::GeoIPManager::instance()->lookup(host)); + qDebug("Banning peer %s...", ip.toLocal8Bit().data()); +- Logger::instance()->addMessage(tr("Manually banning peer '%1'...").arg(ip)); ++ Logger::instance()->addMessage(tr("Manually banning peer '%1'...'%2'...'%3'...'%4'").arg(ip).arg(peerid).arg(client).arg(countryName)); + BitTorrent::Session::instance()->banIP(ip); + } + // Refresh list +@@ -398,6 +404,7 @@ QStandardItem *PeerListWidget::addPeer(c + m_listModel->setData(m_listModel->index(row, PeerListDelegate::FLAGS), peer.flags()); + m_listModel->setData(m_listModel->index(row, PeerListDelegate::FLAGS), peer.flagsDescription(), Qt::ToolTipRole); + m_listModel->setData(m_listModel->index(row, PeerListDelegate::CLIENT), peer.client().toHtmlEscaped()); ++ m_listModel->setData(m_listModel->index(row, PeerListDelegate::PEERID), peer.pid().left(8).toHtmlEscaped()); + m_listModel->setData(m_listModel->index(row, PeerListDelegate::PROGRESS), peer.progress()); + m_listModel->setData(m_listModel->index(row, PeerListDelegate::DOWN_SPEED), peer.payloadDownSpeed()); + m_listModel->setData(m_listModel->index(row, PeerListDelegate::UP_SPEED), peer.payloadUpSpeed()); +@@ -429,6 +436,7 @@ void PeerListWidget::updatePeer(const QS + m_listModel->setData(m_listModel->index(row, PeerListDelegate::FLAGS), peer.flags()); + m_listModel->setData(m_listModel->index(row, PeerListDelegate::FLAGS), peer.flagsDescription(), Qt::ToolTipRole); + m_listModel->setData(m_listModel->index(row, PeerListDelegate::CLIENT), peer.client().toHtmlEscaped()); ++ m_listModel->setData(m_listModel->index(row, PeerListDelegate::PEERID), peer.pid().left(8).toHtmlEscaped()); + m_listModel->setData(m_listModel->index(row, PeerListDelegate::PROGRESS), peer.progress()); + m_listModel->setData(m_listModel->index(row, PeerListDelegate::DOWN_SPEED), peer.payloadDownSpeed()); + m_listModel->setData(m_listModel->index(row, PeerListDelegate::UP_SPEED), peer.payloadUpSpeed()); +--- a/src/webui/api/appcontroller.cpp ++++ b/src/webui/api/appcontroller.cpp +@@ -153,6 +153,7 @@ void AppController::preferencesAction() + data["ip_filter_path"] = Utils::Fs::toNativePath(session->IPFilterFile()); + data["ip_filter_trackers"] = session->isTrackerFilteringEnabled(); + data["banned_IPs"] = session->bannedIPs().join("\n"); ++ data["auto_ban_unknown_peer"] = session->isAutoBanUnknownPeerEnabled(); + + // Speed + // Global Rate Limits +@@ -401,6 +402,8 @@ void AppController::setPreferencesAction + session->setTrackerFilteringEnabled(m["ip_filter_trackers"].toBool()); + if (m.contains("banned_IPs")) + session->setBannedIPs(m["banned_IPs"].toString().split('\n')); ++ if (m.contains("auto_ban_unknown_peer")) ++ session->setAutoBanUnknownPeer(m["auto_ban_unknown_peer"].toBool()); + + // Speed + // Global Rate Limits +--- a/src/webui/api/transfercontroller.cpp ++++ b/src/webui/api/transfercontroller.cpp +@@ -30,6 +30,7 @@ + + #include + ++#include "base/logger.h" + #include "base/bittorrent/session.h" + + const char KEY_TRANSFER_DLSPEED[] = "dl_info_speed"; +@@ -111,3 +112,37 @@ void TransferController::speedLimitsMode + { + setResult(QString::number(BitTorrent::Session::instance()->isAltGlobalSpeedLimitEnabled())); + } ++ ++void TransferController::tempblockPeerAction() ++{ ++ checkParams({"ip"}); ++ QString ip = params()["ip"]; ++ boost::system::error_code ec; ++ boost::asio::ip::address addr = boost::asio::ip::address::from_string(ip.toStdString(), ec); ++ bool isBanned = BitTorrent::Session::instance()->checkAccessFlags(QString::fromStdString(addr.to_string())); ++ ++ if (ip.isEmpty()) { ++ setResult(QLatin1String("IP field should not be empty.")); ++ return; ++ } ++ ++ if (ec) { ++ setResult(QLatin1String("The given IP address is not valid.")); ++ return; ++ } ++ ++ if (isBanned) { ++ setResult(QLatin1String("The given IP address already exists.")); ++ return; ++ } ++ ++ BitTorrent::Session::instance()->tempblockIP(ip); ++ Logger::instance()->addMessage(tr("Peer '%1' banned via Web API.").arg(ip)); ++ setResult(QLatin1String("Done.")); ++} ++ ++void TransferController::resetIPFilterAction() ++{ ++ BitTorrent::Session::instance()->eraseIPFilter(); ++ setResult(QLatin1String("Erased.")); ++} +--- a/src/webui/api/transfercontroller.h ++++ b/src/webui/api/transfercontroller.h +@@ -46,4 +46,6 @@ private slots: + void downloadLimitAction(); + void setUploadLimitAction(); + void setDownloadLimitAction(); ++ void tempblockPeerAction(); ++ void resetIPFilterAction(); + }; +--- a/src/webui/www/private/preferences_content.html ++++ b/src/webui/www/private/preferences_content.html +@@ -377,6 +377,8 @@ + + + ++ ++ + + + +@@ -1252,6 +1254,7 @@ + $('ipfilter_text').setProperty('value', pref.ip_filter_path); + $('ipfilter_trackers_checkbox').setProperty('checked', pref.ip_filter_trackers); + $('banned_IPs_textarea').setProperty('value', pref.banned_IPs); ++ $('auto_ban_unknown_peer_checkbox').setProperty('checked', pref.auto_ban_unknown_peer); + updateFilterSettings(); + + // Speed tab +@@ -1502,6 +1505,7 @@ + settings.set('ip_filter_path', $('ipfilter_text').getProperty('value')); + settings.set('ip_filter_trackers', $('ipfilter_trackers_checkbox').getProperty('checked')); + settings.set('banned_IPs', $('banned_IPs_textarea').getProperty('value')); ++ settings.set('auto_ban_unknown_peer', $('auto_ban_unknown_peer_checkbox').getProperty('checked')); + + // Speed tab + // Global Rate Limits diff --git a/package/lean/qt5/Makefile b/package/lean/qt5/Makefile index 739bfb33f4..8d51639e12 100644 --- a/package/lean/qt5/Makefile +++ b/package/lean/qt5/Makefile @@ -1,136 +1,177 @@ # -# Copyright (C) 2013 Riccardo Ferrazzo -# Copyright (C) 2017 Paweł Knioła +# Copyright (C) 2017-2019 Entware # # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. # +# ported to Entware from +# https://github.com/KryptonLee/qBittorrent-openwrt-package and +# https://github.com/pawelkn/qt5-openwrt-package include $(TOPDIR)/rules.mk PKG_NAME:=qt5 -PKG_VERSION:=5.13 +PKG_VERSION:=5.9.8 PKG_RELEASE:=1 -PKG_MD5SUM:=d66b1da335d0c25325fdf493e9044c38 -PKG_SOURCE:=qt-everywhere-src-$(PKG_VERSION).$(PKG_RELEASE).tar.xz -PKG_SOURCE_URL:=http://download.qt-project.org/archive/qt/$(PKG_VERSION)/$(PKG_VERSION).$(PKG_RELEASE)/single -PKG_BUILD_DIR=$(BUILD_DIR)/qt-everywhere-src-$(PKG_VERSION).$(PKG_RELEASE) +PKG_SOURCE:=qt-everywhere-opensource-src-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=http://download.qt-project.org/archive/qt/5.9/$(PKG_VERSION)/single +PKG_HASH:=86aca7dc37f161fc730a9d4f6bddf684962ca560327682e282ff61bf8b859c36 + PKG_BUILD_PARALLEL:=1 PKG_USE_MIPS16:=0 +PKG_BUILD_DIR=$(BUILD_DIR)/qt-everywhere-opensource-src-$(PKG_VERSION) include $(INCLUDE_DIR)/package.mk +ifndef CONFIG_USE_GLIBC # not using sstrip here as this fucks up the .so's somehow STRIP:=/bin/true RSTRIP:= \ - NM="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)nm" \ - STRIP="$(STRIP)" \ - STRIP_KMOD="$(STRIP)" \ - $(SCRIPT_DIR)/rstrip.sh + NM="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)nm" \ + STRIP="$(STRIP)" \ + STRIP_KMOD="$(STRIP)" \ + $(SCRIPT_DIR)/rstrip.sh +endif define Package/qt5/Default - SECTION:=libs - CATEGORY:=Libraries - SUBMENU:=Qt5 - TITLE:=qt5 - URL:=http://qt-project.org - DEPENDS:=+libatomic +libstdcpp +libopenssl +zlib +icu @!LINUX_2_6 + SECTION:=libs + CATEGORY:=Libraries + SUBMENU:=Qt5 + TITLE:=qt5 + URL:=http://qt-project.org + DEPENDS:=+librt +libstdcpp +libpthread @!LINUX_2_6_36 endef define Package/qt5-core - $(call Package/qt5/Default) - TITLE+=core -endef - -define Package/qt5-concurrent - $(call Package/qt5/Default) - TITLE+=concurrent - DEPENDS+=+qt5-core + $(call Package/qt5/Default) + TITLE+=core + DEPENDS+=+libatomic +zlib +libpcre2-16 +libdouble-conversion endef define Package/qt5-network - $(call Package/qt5/Default) - TITLE+=network - DEPENDS+=+qt5-core -endef - -define Package/qt5-widgets - $(call Package/qt5/Default) - TITLE+=widgets - DEPENDS+=+qt5-core +qt5-network -endef - -define Package/qt5-sql - $(call Package/qt5/Default) - TITLE+=sql - DEPENDS+=+qt5-core +libmariadbclient + $(call Package/qt5/Default) + TITLE+=network + DEPENDS+=+qt5-core +libopenssl endef define Package/qt5-xml - $(call Package/qt5/Default) - TITLE+=xml - DEPENDS+=+qt5-core + $(call Package/qt5/Default) + TITLE+=xml + DEPENDS+=+qt5-core endef -define Package/qt5-serialport - $(call Package/qt5/Default) - TITLE+=serialport - DEPENDS+=+qt5-core -endef - -define Package/qt5-xmlpatterns - $(call Package/qt5/Default) - TITLE+=xmlpatterns - DEPENDS+=+qt5-core +qt5-network -endef - -define Package/qt5-test - $(call Package/qt5/Default) - TITLE+=test - DEPENDS+=+qt5-core -endef +CONFIGURE_ARGS = \ + -prefix /usr \ + -sysroot $(STAGING_DIR) \ + -plugindir /usr/lib/Qt/plugins \ + -R /usr/lib \ + -I $(STAGING_DIR)/usr/include \ + -L $(STAGING_DIR)/usr/lib \ + -xplatform linux-openwrt-g++ \ + -release \ + -shared \ + -opensource \ + -confirm-license \ + -no-use-gold-linker \ + -strip \ + -ltcg \ + -optimized-qmake \ + -system-doubleconversion \ + -no-glib \ + -no-icu \ + -system-pcre \ + -system-zlib \ + -no-slog2 \ + -openssl-linked \ + -no-cups \ + -no-freetype \ + -no-harfbuzz \ + -no-gtk \ + -no-opengl \ + -no-opengles3 \ + -no-angle \ + -no-openvg \ + -no-directfb \ + -no-eglfs \ + -no-egl \ + -no-iconv \ + -no-gbm \ + -no-kms \ + -no-xcb \ + -no-pch \ + -no-libudev \ + -no-mtdev \ + -no-tslib \ + -no-xkbcommon-evdev \ + -no-libpng \ + -no-libjpeg \ + -no-sql-db2 \ + -no-sql-ibase \ + -no-sql-mysql \ + -no-sql-oci \ + -no-sql-odbc \ + -no-sql-psql \ + -no-sql-sqlite \ + -no-sql-sqlite2 \ + -no-sqlite \ + -no-sql-tds \ + -no-gui \ + -no-widgets \ + -no-dbus \ + -no-qml-debug \ + -make libs \ + -nomake examples \ + -nomake tests \ + -nomake tools \ + -no-compile-examples \ + -skip qt3d \ + -skip qtactiveqt \ + -skip qtandroidextras \ + -skip qtcanvas3d \ + -skip qtcharts \ + -skip qtconnectivity \ + -skip qtdatavis3d \ + -skip qtdeclarative \ + -skip qtdoc \ + -skip qtgamepad \ + -skip qtgraphicaleffects \ + -skip qtimageformats \ + -skip qtlocation \ + -skip qtmacextras \ + -skip qtmultimedia \ + -skip qtnetworkauth \ + -skip qtpurchasing \ + -skip qtquickcontrols \ + -skip qtquickcontrols2 \ + -skip qtremoteobjects \ + -skip qtscript \ + -skip qtscxml \ + -skip qtsensors \ + -skip qtserialbus \ + -skip qtserialport \ + -skip qtspeech \ + -skip qtsvg \ + -skip qttranslations \ + -skip qtvirtualkeyboard \ + -skip qtwayland \ + -skip qtwebchannel \ + -skip qtwebengine \ + -skip qtwebsockets \ + -skip qtwebview \ + -skip qtwinextras \ + -skip qtx11extras \ + -skip qtxmlpatterns \ + -v define Build/Configure - $(INSTALL_DIR) $(PKG_BUILD_DIR)/qtbase/mkspecs/linux-openwrt-g++ - $(CP) ./files/qplatformdefs.h $(PKG_BUILD_DIR)/qtbase/mkspecs/linux-openwrt-g++/qplatformdefs.h - $(CP) ./files/qmake.conf $(PKG_BUILD_DIR)/qtbase/mkspecs/linux-openwrt-g++/qmake.conf $(SED) 's@$$$$(TARGET_CROSS)@$(TARGET_CROSS)@g' $(PKG_BUILD_DIR)/qtbase/mkspecs/linux-openwrt-g++/qmake.conf - ( cd $(PKG_BUILD_DIR) ; \ - ./configure \ - -prefix $(TOOLCHAIN_DIR) \ - -xplatform linux-openwrt-g++ \ - -opensource \ - -confirm-license \ - -no-iconv \ - -no-pch \ - -no-rpath \ - -no-strip \ - -no-cups \ - -no-dbus \ - -no-eglfs \ - -no-kms \ - -no-opengl \ - -no-directfb \ - -no-xcb \ - -openssl-runtime \ - -qt-zlib \ - -qt-pcre \ - -qt-freetype \ - -make libs \ - -nomake examples \ - -nomake tools \ - -nomake tests \ - -skip qtdeclarative \ - -skip qtmultimedia \ - -skip activeqt \ - -skip qtdoc \ - -skip qtconnectivity \ - -skip wayland \ - -skip qtscript \ - -v \ - ) + $(SED) 's@$$$$(TARGET_CFLAGS)@$(TARGET_CFLAGS)@g' $(PKG_BUILD_DIR)/qtbase/mkspecs/linux-openwrt-g++/qmake.conf + $(SED) 's@$$$$(TARGET_CXXFLAGS)@$(TARGET_CXXFLAGS)@g' $(PKG_BUILD_DIR)/qtbase/mkspecs/linux-openwrt-g++/qmake.conf + $(SED) 's@$$$$(TARGET_LDFLAGS)@$(TARGET_LDFLAGS)@g' $(PKG_BUILD_DIR)/qtbase/mkspecs/linux-openwrt-g++/qmake.conf + + $(call Build/Configure/Default) endef define Build/Compile @@ -139,95 +180,25 @@ endef define Build/InstallDev $(MAKE) -C $(PKG_BUILD_DIR) install - $(CP) $(PKG_BUILD_DIR)/qtbase/bin/qmake $(TOOLCHAIN_DIR)/bin/ - $(CP) $(PKG_BUILD_DIR)/qtbase/bin/qt.conf $(TOOLCHAIN_DIR)/bin/ + $(INSTALL_CONF) $(PKG_BUILD_DIR)/qtbase/bin/qt.conf $(STAGING_DIR)/usr/bin + $(RM) $(STAGING_DIR)/usr/bin/qt{attributionsscanner,paths,plugininfo} endef define Package/qt5-core/install - $(INSTALL_DIR) $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Core.so* $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Core.prl $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Core.la $(1)/usr/lib/ -endef - -define Package/qt5-concurrent/install - $(INSTALL_DIR) $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Concurrent.so* $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Concurrent.prl $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Concurrent.la $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Core.so* $(1)/usr/lib endef define Package/qt5-network/install - $(INSTALL_DIR) $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Network.so* $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Network.prl $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Network.la $(1)/usr/lib/ -endef - -define Package/qt5-widgets/install - $(INSTALL_DIR) $(1)/usr/lib/ - $(INSTALL_DIR) $(1)/usr/lib/Qt/plugins/generic/ - $(INSTALL_DIR) $(1)/usr/lib/Qt/plugins/platforms/ - $(INSTALL_DIR) $(1)/usr/lib/Qt/plugins/imageformats/ - $(INSTALL_DIR) $(1)/usr/lib/fonts/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Gui.so* $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Gui.prl $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Gui.la $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtsvg/lib/libQt5Svg.so* $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtsvg/lib/libQt5Svg.prl $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtsvg/lib/libQt5Svg.la $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Widgets.so* $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Widgets.prl $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Widgets.la $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/plugins/generic/*.so $(1)/usr/lib/Qt/plugins/generic/ - $(CP) $(PKG_BUILD_DIR)/qtbase/plugins/platforms/*.so $(1)/usr/lib/Qt/plugins/platforms/ - $(CP) $(PKG_BUILD_DIR)/qtbase/plugins/imageformats/*.so $(1)/usr/lib/Qt/plugins/imageformats/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/fonts/* $(1)/usr/lib/fonts/ -endef - -define Package/qt5-sql/install - $(INSTALL_DIR) $(1)/usr/lib/ - $(INSTALL_DIR) $(1)/usr/lib/Qt/plugins/sqldrivers/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Sql.so* $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Sql.prl $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Sql.la $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/plugins/sqldrivers/*.so $(1)/usr/lib/Qt/plugins/sqldrivers/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Network.so* $(1)/usr/lib endef define Package/qt5-xml/install - $(INSTALL_DIR) $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Xml.so* $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Xml.prl $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Xml.la $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Xml.so* $(1)/usr/lib endef -define Package/qt5-serialport/install - $(INSTALL_DIR) $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtserialport/lib/libQt5SerialPort.so* $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtserialport/lib/libQt5SerialPort.prl $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtserialport/lib/libQt5SerialPort.la $(1)/usr/lib/ -endef - -define Package/qt5-xmlpatterns/install - $(INSTALL_DIR) $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtxmlpatterns/lib/libQt5XmlPatterns.so* $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtxmlpatterns/lib/libQt5XmlPatterns.prl $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtxmlpatterns/lib/libQt5XmlPatterns.la $(1)/usr/lib/ -endef - -define Package/qt5-test/install - $(INSTALL_DIR) $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Test.so* $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Test.prl $(1)/usr/lib/ - $(CP) $(PKG_BUILD_DIR)/qtbase/lib/libQt5Test.la $(1)/usr/lib/ -endef - -$(eval $(call BuildPackage,qt5-core)) -$(eval $(call BuildPackage,qt5-concurrent)) +$(eval $(call BuildPackage,qt5-core,+zlib,+libpcre2-16,+libdouble-conversion)) $(eval $(call BuildPackage,qt5-network)) -$(eval $(call BuildPackage,qt5-widgets)) -$(eval $(call BuildPackage,qt5-sql)) $(eval $(call BuildPackage,qt5-xml)) -$(eval $(call BuildPackage,qt5-serialport)) -$(eval $(call BuildPackage,qt5-xmlpatterns)) -$(eval $(call BuildPackage,qt5-test)) diff --git a/package/lean/qt5/files/qplatformdefs.h b/package/lean/qt5/files/qplatformdefs.h deleted file mode 100644 index aedffeb1ef..0000000000 --- a/package/lean/qt5/files/qplatformdefs.h +++ /dev/null @@ -1,40 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "../linux-g++/qplatformdefs.h" diff --git a/package/lean/qt5/patches/010-pre_3.6_kernels_fix.patch b/package/lean/qt5/patches/010-pre_3.6_kernels_fix.patch new file mode 100644 index 0000000000..818e4efcdd --- /dev/null +++ b/package/lean/qt5/patches/010-pre_3.6_kernels_fix.patch @@ -0,0 +1,74 @@ +--- a/qtserialbus/src/plugins/canbus/socketcan/socketcanbackend.cpp ++++ b/qtserialbus/src/plugins/canbus/socketcan/socketcanbackend.cpp +@@ -33,7 +33,6 @@ + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ +- + #include "socketcanbackend.h" + + #include +@@ -50,29 +49,7 @@ + #include + #include + +-#ifndef CANFD_MTU +-// CAN FD support was added by Linux kernel 3.6 +-// For prior kernels we redefine the missing defines here +-// they are taken from linux/can/raw.h & linux/can.h +- +-enum { +- CAN_RAW_FD_FRAMES = 5 +-}; +- +-#define CAN_MAX_DLEN 8 +-#define CANFD_MAX_DLEN 64 +-struct canfd_frame { +- canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ +- __u8 len; /* frame payload length in byte */ +- __u8 flags; /* additional flags for CAN FD */ +- __u8 __res0; /* reserved / padding */ +- __u8 __res1; /* reserved / padding */ +- __u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8))); +-}; +-#define CAN_MTU (sizeof(struct can_frame)) +-#define CANFD_MTU (sizeof(struct canfd_frame)) + +-#endif + + #ifndef CANFD_BRS + # define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */ +--- a/qtserialbus/src/plugins/canbus/socketcan/socketcanbackend.h ++++ b/qtserialbus/src/plugins/canbus/socketcan/socketcanbackend.h +@@ -45,6 +45,31 @@ + #include + #include + ++#ifndef CANFD_MTU ++// CAN FD support was added by Linux kernel 3.6 ++// For prior kernels we redefine the missing defines here ++// they are taken from linux/can/raw.h & linux/can.h ++ ++enum { ++ CAN_RAW_FD_FRAMES = 5 ++}; ++ ++#define CAN_MAX_DLEN 8 ++#define CANFD_MAX_DLEN 64 ++struct canfd_frame { ++ canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ ++ __u8 len; /* frame payload length in byte */ ++ __u8 flags; /* additional flags for CAN FD */ ++ __u8 __res0; /* reserved / padding */ ++ __u8 __res1; /* reserved / padding */ ++ __u8 data[CANFD_MAX_DLEN] __attribute__((aligned(8))); ++}; ++#define CAN_MTU (sizeof(struct can_frame)) ++#define CANFD_MTU (sizeof(struct canfd_frame)) ++ ++#endif ++ ++ + QT_BEGIN_NAMESPACE + + class SocketCanBackend : public QCanBusDevice diff --git a/package/lean/qt5/patches/020-disable_unused_libs.patch b/package/lean/qt5/patches/020-disable_unused_libs.patch new file mode 100644 index 0000000000..e32bae7647 --- /dev/null +++ b/package/lean/qt5/patches/020-disable_unused_libs.patch @@ -0,0 +1,91 @@ +This patch disables prinstsupport, sql, concurrent, testlib base libs compilation +--- a/qtbase/src/src.pro ++++ b/qtbase/src/src.pro +@@ -66,22 +66,10 @@ src_dbus.target = sub-dbus + src_dbus.depends = src_corelib + force_dbus_bootstrap: src_dbus.depends += src_tools_bootstrap_dbus # avoid syncqt race + +-src_concurrent.subdir = $$PWD/concurrent +-src_concurrent.target = sub-concurrent +-src_concurrent.depends = src_corelib +- +-src_sql.subdir = $$PWD/sql +-src_sql.target = sub-sql +-src_sql.depends = src_corelib +- + src_network.subdir = $$PWD/network + src_network.target = sub-network + src_network.depends = src_corelib + +-src_testlib.subdir = $$PWD/testlib +-src_testlib.target = sub-testlib +-src_testlib.depends = src_corelib # testlib links only to corelib, but see below for the headers +- + src_3rdparty_pcre2.subdir = $$PWD/3rdparty/pcre2 + src_3rdparty_pcre2.target = sub-3rdparty-pcre2 + +@@ -125,13 +113,6 @@ src_openglextensions.subdir = $$PWD/open + src_openglextensions.target = sub-openglextensions + src_openglextensions.depends = src_gui + +-src_printsupport.subdir = $$PWD/printsupport +-src_printsupport.target = sub-printsupport +-src_printsupport.depends = src_corelib src_gui src_widgets src_tools_uic +- +-src_plugins.subdir = $$PWD/plugins +-src_plugins.target = sub-plugins +- + src_android.subdir = $$PWD/android + + # this order is important +@@ -152,14 +133,8 @@ TOOLS = src_tools_moc src_tools_rcc src_ + win32:SUBDIRS += src_winmain + qtConfig(network) { + SUBDIRS += src_network +- src_plugins.depends += src_network +-} +-qtConfig(sql) { +- SUBDIRS += src_sql +- src_plugins.depends += src_sql + } + qtConfig(xml): SUBDIRS += src_xml +-qtConfig(testlib): SUBDIRS += src_testlib + qtConfig(dbus) { + force_dbus_bootstrap|qtConfig(private_tests): \ + SUBDIRS += src_tools_bootstrap_dbus +@@ -167,9 +142,7 @@ qtConfig(dbus) { + TOOLS += src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml + qtConfig(accessibility-atspi-bridge): \ + src_platformsupport.depends += src_dbus src_tools_qdbusxml2cpp +- src_plugins.depends += src_dbus src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml + } +-qtConfig(concurrent): SUBDIRS += src_concurrent + qtConfig(gui) { + qtConfig(harfbuzz):!qtConfig(system-harfbuzz) { + SUBDIRS += src_3rdparty_harfbuzzng +@@ -190,24 +163,17 @@ qtConfig(gui) { + } + SUBDIRS += src_gui src_platformsupport src_platformheaders + qtConfig(opengl): SUBDIRS += src_openglextensions +- src_plugins.depends += src_gui src_platformsupport src_platformheaders +- src_testlib.depends += src_gui # if QtGui is enabled, QtTest requires QtGui's headers + qtConfig(widgets) { + SUBDIRS += src_tools_uic src_widgets + !android-embedded: SUBDIRS += src_printsupport + TOOLS += src_tools_uic +- src_plugins.depends += src_widgets +- !android-embedded: src_plugins.depends += src_printsupport +- src_testlib.depends += src_widgets # if QtWidgets is enabled, QtTest requires QtWidgets's headers + qtConfig(opengl) { + SUBDIRS += src_opengl +- src_plugins.depends += src_opengl + } + } + } +-SUBDIRS += src_plugins + +-nacl: SUBDIRS -= src_network src_testlib ++nacl: SUBDIRS -= src_network + + android:!android-embedded: SUBDIRS += src_android src_3rdparty_gradle + diff --git a/package/lean/qt5/patches/030-qtbase-fix-compile-with-openssl1.1.1.patch b/package/lean/qt5/patches/030-qtbase-fix-compile-with-openssl1.1.1.patch new file mode 100644 index 0000000000..b68ac8e335 --- /dev/null +++ b/package/lean/qt5/patches/030-qtbase-fix-compile-with-openssl1.1.1.patch @@ -0,0 +1,3985 @@ +commit 2d88fc0ce4ac76924a65ffd797183de9422ba672 +Author: Andreas Rammhold +Date: Wed Mar 6 00:18:51 2019 +0100 + + openssl1.1 compat + +diff --git a/qtbase/config.tests/openssl/openssl.cpp b/qtbase/config.tests/openssl/openssl.cpp +index 6c8a9e8f19..d33b62389c 100644 +--- a/qtbase/config.tests/openssl/openssl.cpp ++++ b/qtbase/config.tests/openssl/openssl.cpp +@@ -39,8 +39,8 @@ + + #include + +-#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10000000L || OPENSSL_VERSION_NUMBER-0 >= 0x10100000L +-# error "OpenSSL >= 1.0.0, and < 1.1.0 is required" ++#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10000000L ++# error "OpenSSL >= 1.0.0 is required" + #endif + + #include +diff --git a/qtbase/config.tests/openssl11/openssl.cpp b/qtbase/config.tests/openssl11/openssl.cpp +new file mode 100644 +index 0000000000..c20cc59deb +--- /dev/null ++++ b/qtbase/config.tests/openssl11/openssl.cpp +@@ -0,0 +1,48 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2017 The Qt Company Ltd. ++** Contact: https://www.qt.io/licensing/ ++** ++** This file is part of the config.tests of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see https://www.qt.io/terms-conditions. For further ++** information use the contact form at https://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 3 as published by the Free Software ++** Foundation and appearing in the file LICENSE.LGPL3 included in the ++** packaging of this file. Please review the following information to ++** ensure the GNU Lesser General Public License version 3 requirements ++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ++** ++** GNU General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU ++** General Public License version 2.0 or (at your option) the GNU General ++** Public license version 3 or any later version approved by the KDE Free ++** Qt Foundation. The licenses are as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ++** included in the packaging of this file. Please review the following ++** information to ensure the GNU General Public License requirements will ++** be met: https://www.gnu.org/licenses/gpl-2.0.html and ++** https://www.gnu.org/licenses/gpl-3.0.html. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++#include ++ ++#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x10100000L ++# error "OpenSSL >= 1.1 is required" ++#endif ++ ++int main() ++{ ++} +diff --git a/qtbase/config.tests/openssl11/openssl11.pro b/qtbase/config.tests/openssl11/openssl11.pro +new file mode 100644 +index 0000000000..a023aee4aa +--- /dev/null ++++ b/qtbase/config.tests/openssl11/openssl11.pro +@@ -0,0 +1,2 @@ ++SOURCES = openssl.cpp ++CONFIG -= x11 qt +diff --git a/qtbase/src/network/configure.json b/qtbase/src/network/configure.json +index 2cf90ed94b..a021c0734b 100644 +--- a/qtbase/src/network/configure.json ++++ b/qtbase/src/network/configure.json +@@ -77,6 +77,17 @@ + }, + { "libs": "-lssl -lcrypto", "condition": "!config.win32" } + ] ++ }, ++ "openssl11": { ++ "label": "OpenSSL v. 1.1 support", ++ "type": "compile", ++ "test": "openssl11", ++ "sources": [ ++ { ++ "comment": "placeholder for OPENSSL_PATH", ++ "libs": "" ++ } ++ ] + } + }, + +@@ -182,7 +193,7 @@ + "enable": "input.openssl == 'yes' || input.openssl == 'linked' || input.openssl == 'runtime'", + "disable": "input.openssl == 'no' || input.ssl == 'no'", + "autoDetect": "!config.winrt", +- "condition": "!features.securetransport && (features.openssl-linked || libs.openssl_headers)", ++ "condition": "!features.securetransport && (features.openssl-linked || libs.openssl_headers || feature.opensslv11)", + "output": [ + "privateFeature", + { "type": "publicQtConfig", "condition": "!features.openssl-linked" }, +@@ -193,7 +204,7 @@ + "label": " Qt directly linked to OpenSSL", + "enable": "input.openssl == 'linked'", + "disable": "input.openssl != 'linked'", +- "condition": "!features.securetransport && libs.openssl", ++ "condition": "!features.securetransport && (libs.openssl || feature.opensslv11)", + "output": [ + "privateFeature", + { "type": "define", "name": "QT_LINKED_OPENSSL" } +@@ -213,6 +224,11 @@ + "condition": "config.winrt || features.securetransport || features.openssl", + "output": [ "publicFeature", "feature" ] + }, ++ "opensslv11": { ++ "label": "OpenSSL v. 1.1", ++ "condition": "libs.openssl11", ++ "output": ["publicFeature", "feature"] ++ }, + "sctp": { + "label": "SCTP", + "autoDetect": false, +diff --git a/qtbase/src/network/ssl/qsslcertificate_openssl.cpp b/qtbase/src/network/ssl/qsslcertificate_openssl.cpp +index 28b7eda54a..71e514a025 100644 +--- a/qtbase/src/network/ssl/qsslcertificate_openssl.cpp ++++ b/qtbase/src/network/ssl/qsslcertificate_openssl.cpp +@@ -1,6 +1,7 @@ + /**************************************************************************** + ** +-** Copyright (C) 2016 The Qt Company Ltd. ++** Copyright (C) 2017 The Qt Company Ltd. ++** Copyright (C) 2016 Richard J. Moore + ** Contact: https://www.qt.io/licensing/ + ** + ** This file is part of the QtNetwork module of the Qt Toolkit. +@@ -64,12 +65,14 @@ bool QSslCertificate::operator==(const QSslCertificate &other) const + uint qHash(const QSslCertificate &key, uint seed) Q_DECL_NOTHROW + { + if (X509 * const x509 = key.d->x509) { +- (void)q_X509_cmp(x509, x509); // populate x509->sha1_hash +- // (if someone knows a better way...) +- return qHashBits(x509->sha1_hash, SHA_DIGEST_LENGTH, seed); +- } else { +- return seed; ++ const EVP_MD *sha1 = q_EVP_sha1(); ++ unsigned int len = 0; ++ unsigned char md[EVP_MAX_MD_SIZE]; ++ q_X509_digest(x509, sha1, md, &len); ++ return qHashBits(md, len, seed); + } ++ ++ return seed; + } + + bool QSslCertificate::isNull() const +@@ -89,8 +92,7 @@ QByteArray QSslCertificate::version() const + { + QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); + if (d->versionString.isEmpty() && d->x509) +- d->versionString = +- QByteArray::number(qlonglong(q_ASN1_INTEGER_get(d->x509->cert_info->version)) + 1); ++ d->versionString = QByteArray::number(qlonglong(q_X509_get_version(d->x509)) + 1); + + return d->versionString; + } +@@ -99,7 +101,7 @@ QByteArray QSslCertificate::serialNumber() const + { + QMutexLocker lock(QMutexPool::globalInstanceGet(d.data())); + if (d->serialNumberString.isEmpty() && d->x509) { +- ASN1_INTEGER *serialNumber = d->x509->cert_info->serialNumber; ++ ASN1_INTEGER *serialNumber = q_X509_get_serialNumber(d->x509); + QByteArray hexString; + hexString.reserve(serialNumber->length * 3); + for (int a = 0; a < serialNumber->length; ++a) { +@@ -199,14 +201,15 @@ QMultiMap QSslCertificate::subjectAlter + continue; + } + +- const char *altNameStr = reinterpret_cast(q_ASN1_STRING_data(genName->d.ia5)); ++ const char *altNameStr = reinterpret_cast(q_ASN1_STRING_get0_data(genName->d.ia5)); + const QString altName = QString::fromLatin1(altNameStr, len); + if (genName->type == GEN_DNS) + result.insert(QSsl::DnsEntry, altName); + else if (genName->type == GEN_EMAIL) + result.insert(QSsl::EmailEntry, altName); + } +- q_sk_pop_free((STACK*)altNames, reinterpret_cast(q_sk_free)); ++ ++ q_OPENSSL_sk_pop_free((OPENSSL_STACK*)altNames, reinterpret_cast(q_OPENSSL_sk_free)); + } + + return result; +@@ -235,25 +238,26 @@ QSslKey QSslCertificate::publicKey() const + QSslKey key; + + key.d->type = QSsl::PublicKey; +- X509_PUBKEY *xkey = d->x509->cert_info->key; +- EVP_PKEY *pkey = q_X509_PUBKEY_get(xkey); ++ ++ EVP_PKEY *pkey = q_X509_get_pubkey(d->x509); + Q_ASSERT(pkey); ++ const int keyType = q_EVP_PKEY_type(q_EVP_PKEY_base_id(pkey)); + +- if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA) { ++ if (keyType == EVP_PKEY_RSA) { + key.d->rsa = q_EVP_PKEY_get1_RSA(pkey); + key.d->algorithm = QSsl::Rsa; + key.d->isNull = false; +- } else if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_DSA) { ++ } else if (keyType == EVP_PKEY_DSA) { + key.d->dsa = q_EVP_PKEY_get1_DSA(pkey); + key.d->algorithm = QSsl::Dsa; + key.d->isNull = false; + #ifndef OPENSSL_NO_EC +- } else if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_EC) { ++ } else if (keyType == EVP_PKEY_EC) { + key.d->ec = q_EVP_PKEY_get1_EC_KEY(pkey); + key.d->algorithm = QSsl::Ec; + key.d->isNull = false; + #endif +- } else if (q_EVP_PKEY_type(pkey->type) == EVP_PKEY_DH) { ++ } else if (keyType == EVP_PKEY_DH) { + // DH unsupported + } else { + // error? +@@ -275,7 +279,7 @@ static QVariant x509UnknownExtensionToValue(X509_EXTENSION *ext) + X509V3_EXT_METHOD *meth = const_cast(q_X509V3_EXT_get(ext)); + if (!meth) { + ASN1_OCTET_STRING *value = q_X509_EXTENSION_get_data(ext); +- QByteArray result( reinterpret_cast(q_ASN1_STRING_data(value)), ++ QByteArray result( reinterpret_cast(q_ASN1_STRING_get0_data(value)), + q_ASN1_STRING_length(value)); + return result; + } +@@ -371,7 +375,7 @@ static QVariant x509ExtensionToValue(X509_EXTENSION *ext) + continue; + } + +- const char *uriStr = reinterpret_cast(q_ASN1_STRING_data(name->d.uniformResourceIdentifier)); ++ const char *uriStr = reinterpret_cast(q_ASN1_STRING_get0_data(name->d.uniformResourceIdentifier)); + const QString uri = QString::fromUtf8(uriStr, len); + + result[QString::fromUtf8(QSslCertificatePrivate::asn1ObjectName(ad->method))] = uri; +@@ -380,11 +384,7 @@ static QVariant x509ExtensionToValue(X509_EXTENSION *ext) + } + } + +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L +- q_sk_pop_free((_STACK*)info, reinterpret_cast(q_sk_free)); +-#else +- q_sk_pop_free((STACK*)info, reinterpret_cast(q_sk_free)); +-#endif ++ q_OPENSSL_sk_pop_free((OPENSSL_STACK*)info, reinterpret_cast(q_OPENSSL_sk_free)); + return result; + } + break; +@@ -607,7 +607,11 @@ static QMap _q_mapFromX509Name(X509_NAME *name) + unsigned char *data = 0; + int size = q_ASN1_STRING_to_UTF8(&data, q_X509_NAME_ENTRY_get_data(e)); + info.insertMulti(name, QString::fromUtf8((char*)data, size)); ++#if QT_CONFIG(opensslv11) ++ q_CRYPTO_free(data, 0, 0); ++#else + q_CRYPTO_free(data); ++#endif + } + + return info; +@@ -619,8 +623,9 @@ QSslCertificate QSslCertificatePrivate::QSslCertificate_from_X509(X509 *x509) + if (!x509 || !QSslSocket::supportsSsl()) + return certificate; + +- ASN1_TIME *nbef = q_X509_get_notBefore(x509); +- ASN1_TIME *naft = q_X509_get_notAfter(x509); ++ ASN1_TIME *nbef = q_X509_getm_notBefore(x509); ++ ASN1_TIME *naft = q_X509_getm_notAfter(x509); ++ + certificate.d->notValidBefore = q_getTimeFromASN1(nbef); + certificate.d->notValidAfter = q_getTimeFromASN1(naft); + certificate.d->null = false; +diff --git a/qtbase/src/network/ssl/qsslcontext_openssl.cpp b/qtbase/src/network/ssl/qsslcontext_openssl.cpp +index c92d8fc3f8..cef503710c 100644 +--- a/qtbase/src/network/ssl/qsslcontext_openssl.cpp ++++ b/qtbase/src/network/ssl/qsslcontext_openssl.cpp +@@ -1,6 +1,6 @@ + /**************************************************************************** + ** +-** Copyright (C) 2016 The Qt Company Ltd. ++** Copyright (C) 2017 The Qt Company Ltd. + ** Copyright (C) 2014 BlackBerry Limited. All rights reserved. + ** Copyright (C) 2014 Governikus GmbH & Co. KG. + ** Contact: https://www.qt.io/licensing/ +@@ -41,22 +41,14 @@ + + + #include +-#include +-#include + + #include "private/qssl_p.h" + #include "private/qsslcontext_openssl_p.h" +-#include "private/qsslsocket_p.h" + #include "private/qsslsocket_openssl_p.h" + #include "private/qsslsocket_openssl_symbols_p.h" +-#include "private/qssldiffiehellmanparameters_p.h" + + QT_BEGIN_NAMESPACE + +-// defined in qsslsocket_openssl.cpp: +-extern int q_X509Callback(int ok, X509_STORE_CTX *ctx); +-extern QString getErrorsFromOpenSsl(); +- + QSslContext::QSslContext() + : ctx(0), + pkey(0), +@@ -78,301 +70,6 @@ QSslContext::~QSslContext() + q_SSL_SESSION_free(session); + } + +-static inline QString msgErrorSettingEllipticCurves(const QString &why) +-{ +- return QSslSocket::tr("Error when setting the elliptic curves (%1)").arg(why); +-} +- +-// static +-void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading) +-{ +- sslContext->sslConfiguration = configuration; +- sslContext->errorCode = QSslError::NoError; +- +- bool client = (mode == QSslSocket::SslClientMode); +- +- bool reinitialized = false; +- bool unsupportedProtocol = false; +-init_context: +- switch (sslContext->sslConfiguration.protocol()) { +- case QSsl::SslV2: +-#ifndef OPENSSL_NO_SSL2 +- sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method()); +-#else +- // SSL 2 not supported by the system, but chosen deliberately -> error +- sslContext->ctx = 0; +- unsupportedProtocol = true; +-#endif +- break; +- case QSsl::SslV3: +-#ifndef OPENSSL_NO_SSL3_METHOD +- sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method()); +-#else +- // SSL 3 not supported by the system, but chosen deliberately -> error +- sslContext->ctx = 0; +- unsupportedProtocol = true; +-#endif +- break; +- case QSsl::SecureProtocols: +- // SSLv2 and SSLv3 will be disabled by SSL options +- // But we need q_SSLv23_server_method() otherwise AnyProtocol will be unable to connect on Win32. +- case QSsl::TlsV1SslV3: +- // SSLv2 will will be disabled by SSL options +- case QSsl::AnyProtocol: +- default: +- sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method()); +- break; +- case QSsl::TlsV1_0: +- sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method()); +- break; +- case QSsl::TlsV1_1: +-#if OPENSSL_VERSION_NUMBER >= 0x10001000L +- sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_1_client_method() : q_TLSv1_1_server_method()); +-#else +- // TLS 1.1 not supported by the system, but chosen deliberately -> error +- sslContext->ctx = 0; +- unsupportedProtocol = true; +-#endif +- break; +- case QSsl::TlsV1_2: +-#if OPENSSL_VERSION_NUMBER >= 0x10001000L +- sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_2_client_method() : q_TLSv1_2_server_method()); +-#else +- // TLS 1.2 not supported by the system, but chosen deliberately -> error +- sslContext->ctx = 0; +- unsupportedProtocol = true; +-#endif +- break; +- case QSsl::TlsV1_0OrLater: +- // Specific protocols will be specified via SSL options. +- sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method()); +- break; +- case QSsl::TlsV1_1OrLater: +- case QSsl::TlsV1_2OrLater: +-#if OPENSSL_VERSION_NUMBER >= 0x10001000L +- // Specific protocols will be specified via SSL options. +- sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method()); +-#else +- // TLS 1.1/1.2 not supported by the system, but chosen deliberately -> error +- sslContext->ctx = 0; +- unsupportedProtocol = true; +-#endif +- break; +- } +- +- if (!sslContext->ctx) { +- // After stopping Flash 10 the SSL library looses its ciphers. Try re-adding them +- // by re-initializing the library. +- if (!reinitialized) { +- reinitialized = true; +- if (q_SSL_library_init() == 1) +- goto init_context; +- } +- +- sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg( +- unsupportedProtocol ? QSslSocket::tr("unsupported protocol") : QSslSocketBackendPrivate::getErrorsFromOpenSsl() +- ); +- sslContext->errorCode = QSslError::UnspecifiedError; +- return; +- } +- +- // Enable bug workarounds. +- long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions); +- q_SSL_CTX_set_options(sslContext->ctx, options); +- +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L +- // Tell OpenSSL to release memory early +- // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html +- if (q_SSLeay() >= 0x10000000L) +- q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS); +-#endif +- +- // Initialize ciphers +- QByteArray cipherString; +- bool first = true; +- QList ciphers = sslContext->sslConfiguration.ciphers(); +- if (ciphers.isEmpty()) +- ciphers = QSslSocketPrivate::defaultCiphers(); +- for (const QSslCipher &cipher : qAsConst(ciphers)) { +- if (first) +- first = false; +- else +- cipherString.append(':'); +- cipherString.append(cipher.name().toLatin1()); +- } +- +- if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, cipherString.data())) { +- sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); +- sslContext->errorCode = QSslError::UnspecifiedError; +- return; +- } +- +- const QDateTime now = QDateTime::currentDateTimeUtc(); +- +- // Add all our CAs to this store. +- const auto caCertificates = sslContext->sslConfiguration.caCertificates(); +- for (const QSslCertificate &caCertificate : caCertificates) { +- // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html: +- // +- // If several CA certificates matching the name, key identifier, and +- // serial number condition are available, only the first one will be +- // examined. This may lead to unexpected results if the same CA +- // certificate is available with different expiration dates. If a +- // ``certificate expired'' verification error occurs, no other +- // certificate will be searched. Make sure to not have expired +- // certificates mixed with valid ones. +- // +- // See also: QSslSocketBackendPrivate::verify() +- if (caCertificate.expiryDate() >= now) { +- q_X509_STORE_add_cert(q_SSL_CTX_get_cert_store(sslContext->ctx), (X509 *)caCertificate.handle()); +- } +- } +- +- if (QSslSocketPrivate::s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) { +- // tell OpenSSL the directories where to look up the root certs on demand +- const QList unixDirs = QSslSocketPrivate::unixRootCertDirectories(); +- for (const QByteArray &unixDir : unixDirs) +- q_SSL_CTX_load_verify_locations(sslContext->ctx, 0, unixDir.constData()); +- } +- +- if (!sslContext->sslConfiguration.localCertificate().isNull()) { +- // Require a private key as well. +- if (sslContext->sslConfiguration.privateKey().isNull()) { +- sslContext->errorStr = QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); +- sslContext->errorCode = QSslError::UnspecifiedError; +- return; +- } +- +- // Load certificate +- if (!q_SSL_CTX_use_certificate(sslContext->ctx, (X509 *)sslContext->sslConfiguration.localCertificate().handle())) { +- sslContext->errorStr = QSslSocket::tr("Error loading local certificate, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); +- sslContext->errorCode = QSslError::UnspecifiedError; +- return; +- } +- +- if (configuration.d->privateKey.algorithm() == QSsl::Opaque) { +- sslContext->pkey = reinterpret_cast(configuration.d->privateKey.handle()); +- } else { +- // Load private key +- sslContext->pkey = q_EVP_PKEY_new(); +- // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free. +- // this lead to a memory leak. Now we use the *_set1_* functions which do not +- // take ownership of the RSA/DSA key instance because the QSslKey already has ownership. +- if (configuration.d->privateKey.algorithm() == QSsl::Rsa) +- q_EVP_PKEY_set1_RSA(sslContext->pkey, reinterpret_cast(configuration.d->privateKey.handle())); +- else if (configuration.d->privateKey.algorithm() == QSsl::Dsa) +- q_EVP_PKEY_set1_DSA(sslContext->pkey, reinterpret_cast(configuration.d->privateKey.handle())); +-#ifndef OPENSSL_NO_EC +- else if (configuration.d->privateKey.algorithm() == QSsl::Ec) +- q_EVP_PKEY_set1_EC_KEY(sslContext->pkey, reinterpret_cast(configuration.d->privateKey.handle())); +-#endif +- } +- +- if (!q_SSL_CTX_use_PrivateKey(sslContext->ctx, sslContext->pkey)) { +- sslContext->errorStr = QSslSocket::tr("Error loading private key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); +- sslContext->errorCode = QSslError::UnspecifiedError; +- return; +- } +- if (configuration.d->privateKey.algorithm() == QSsl::Opaque) +- sslContext->pkey = 0; // Don't free the private key, it belongs to QSslKey +- +- // Check if the certificate matches the private key. +- if (!q_SSL_CTX_check_private_key(sslContext->ctx)) { +- sslContext->errorStr = QSslSocket::tr("Private key does not certify public key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); +- sslContext->errorCode = QSslError::UnspecifiedError; +- return; +- } +- +- // If we have any intermediate certificates then we need to add them to our chain +- bool first = true; +- for (const QSslCertificate &cert : qAsConst(configuration.d->localCertificateChain)) { +- if (first) { +- first = false; +- continue; +- } +- q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, +- q_X509_dup(reinterpret_cast(cert.handle()))); +- } +- } +- +- // Initialize peer verification. +- if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) { +- q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, 0); +- } else { +- q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER, q_X509Callback); +- } +- +- // Set verification depth. +- if (sslContext->sslConfiguration.peerVerifyDepth() != 0) +- q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth()); +- +- // set persisted session if the user set it +- if (!configuration.sessionTicket().isEmpty()) +- sslContext->setSessionASN1(configuration.sessionTicket()); +- +- // Set temp DH params +- QSslDiffieHellmanParameters dhparams = configuration.diffieHellmanParameters(); +- +- if (!dhparams.isValid()) { +- sslContext->errorStr = QSslSocket::tr("Diffie-Hellman parameters are not valid"); +- sslContext->errorCode = QSslError::UnspecifiedError; +- return; +- } +- +- if (!dhparams.isEmpty()) { +- const QByteArray ¶ms = dhparams.d->derData; +- const char *ptr = params.constData(); +- DH *dh = q_d2i_DHparams(NULL, reinterpret_cast(&ptr), params.length()); +- if (dh == NULL) +- qFatal("q_d2i_DHparams failed to convert QSslDiffieHellmanParameters to DER form"); +- q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh); +- q_DH_free(dh); +- } +- +-#ifndef OPENSSL_NO_EC +-#if OPENSSL_VERSION_NUMBER >= 0x10002000L +- if (q_SSLeay() >= 0x10002000L) { +- q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL); +- } else +-#endif +- { +- // Set temp ECDH params +- EC_KEY *ecdh = 0; +- ecdh = q_EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); +- q_SSL_CTX_set_tmp_ecdh(sslContext->ctx, ecdh); +- q_EC_KEY_free(ecdh); +- } +-#endif // OPENSSL_NO_EC +- +-#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK) +- if (!client) +- q_SSL_CTX_use_psk_identity_hint(sslContext->ctx, sslContext->sslConfiguration.preSharedKeyIdentityHint().constData()); +-#endif // OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK) +- +- const QVector qcurves = sslContext->sslConfiguration.ellipticCurves(); +- if (!qcurves.isEmpty()) { +-#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC) +- // Set the curves to be used +- if (q_SSLeay() >= 0x10002000L) { +- // SSL_CTX_ctrl wants a non-const pointer as last argument, +- // but let's avoid a copy into a temporary array +- if (!q_SSL_CTX_ctrl(sslContext->ctx, +- SSL_CTRL_SET_CURVES, +- qcurves.size(), +- const_cast(reinterpret_cast(qcurves.data())))) { +- sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); +- sslContext->errorCode = QSslError::UnspecifiedError; +- } +- } else +-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC) +- { +- // specific curves requested, but not possible to set -> error +- sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("OpenSSL version too old, need at least v1.0.2")); +- sslContext->errorCode = QSslError::UnspecifiedError; +- } +- } +-} +- + QSslContext* QSslContext::fromConfiguration(QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading) + { + QSslContext *sslContext = new QSslContext(); +@@ -463,7 +160,7 @@ SSL* QSslContext::createSsl() + m_npnContext.len = m_supportedNPNVersions.count(); + m_npnContext.status = QSslConfiguration::NextProtocolNegotiationNone; + #if OPENSSL_VERSION_NUMBER >= 0x10002000L +- if (q_SSLeay() >= 0x10002000L) { ++ if (QSslSocket::sslLibraryVersionNumber() >= 0x10002000L) { + // Callback's type has a parameter 'const unsigned char ** out' + // since it was introduced in 1.0.2. Internally, OpenSSL's own code + // (tests/examples) cast it to unsigned char * (since it's 'out'). +@@ -508,7 +205,7 @@ bool QSslContext::cacheSession(SSL* ssl) + unsigned char *data = reinterpret_cast(m_sessionASN1.data()); + if (!q_i2d_SSL_SESSION(session, &data)) + qCWarning(lcSsl, "could not store persistent version of SSL session"); +- m_sessionTicketLifeTimeHint = session->tlsext_tick_lifetime_hint; ++ m_sessionTicketLifeTimeHint = q_SSL_SESSION_get_ticket_lifetime_hint(session); + } + } + +diff --git a/qtbase/src/network/ssl/qsslcontext_openssl11.cpp b/qtbase/src/network/ssl/qsslcontext_openssl11.cpp +new file mode 100644 +index 0000000000..787b6ae3f5 +--- /dev/null ++++ b/qtbase/src/network/ssl/qsslcontext_openssl11.cpp +@@ -0,0 +1,277 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2017 The Qt Company Ltd. ++** Copyright (C) 2014 BlackBerry Limited. All rights reserved. ++** Copyright (C) 2014 Governikus GmbH & Co. KG. ++** Copyright (C) 2016 Richard J. Moore ++** Contact: https://www.qt.io/licensing/ ++** ++** This file is part of the QtNetwork module of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see https://www.qt.io/terms-conditions. For further ++** information use the contact form at https://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 3 as published by the Free Software ++** Foundation and appearing in the file LICENSE.LGPL3 included in the ++** packaging of this file. Please review the following information to ++** ensure the GNU Lesser General Public License version 3 requirements ++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ++** ++** GNU General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU ++** General Public License version 2.0 or (at your option) the GNU General ++** Public license version 3 or any later version approved by the KDE Free ++** Qt Foundation. The licenses are as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ++** included in the packaging of this file. Please review the following ++** information to ensure the GNU General Public License requirements will ++** be met: https://www.gnu.org/licenses/gpl-2.0.html and ++** https://www.gnu.org/licenses/gpl-3.0.html. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++ ++#include ++#include ++ ++#include "private/qssl_p.h" ++#include "private/qsslcontext_openssl_p.h" ++#include "private/qsslsocket_p.h" ++#include "private/qsslsocket_openssl_p.h" ++#include "private/qsslsocket_openssl_symbols_p.h" ++#include "private/qssldiffiehellmanparameters_p.h" ++ ++#include ++ ++QT_BEGIN_NAMESPACE ++ ++// defined in qsslsocket_openssl.cpp: ++extern int q_X509Callback(int ok, X509_STORE_CTX *ctx); ++extern QString getErrorsFromOpenSsl(); ++ ++static inline QString msgErrorSettingEllipticCurves(const QString &why) ++{ ++ return QSslSocket::tr("Error when setting the elliptic curves (%1)").arg(why); ++} ++ ++// static ++void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading) ++{ ++ sslContext->sslConfiguration = configuration; ++ sslContext->errorCode = QSslError::NoError; ++ ++ bool client = (mode == QSslSocket::SslClientMode); ++ ++ bool reinitialized = false; ++ bool unsupportedProtocol = false; ++init_context: ++ if (sslContext->sslConfiguration.protocol() == QSsl::SslV2) { ++ // SSL 2 is no longer supported, but chosen deliberately -> error ++ sslContext->ctx = nullptr; ++ unsupportedProtocol = true; ++ } else { ++ // The ssl options will actually control the supported methods ++ sslContext->ctx = q_SSL_CTX_new(client ? q_TLS_client_method() : q_TLS_server_method()); ++ } ++ ++ if (!sslContext->ctx) { ++ // After stopping Flash 10 the SSL library loses its ciphers. Try re-adding them ++ // by re-initializing the library. ++ if (!reinitialized) { ++ reinitialized = true; ++ if (q_OPENSSL_init_ssl(0, nullptr) == 1) ++ goto init_context; ++ } ++ ++ sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg( ++ unsupportedProtocol ? QSslSocket::tr("unsupported protocol") : QSslSocketBackendPrivate::getErrorsFromOpenSsl() ++ ); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ ++ // Enable bug workarounds. ++ long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions); ++ q_SSL_CTX_set_options(sslContext->ctx, options); ++ ++ // Tell OpenSSL to release memory early ++ // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html ++ q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS); ++ ++ // Initialize ciphers ++ QByteArray cipherString; ++ bool first = true; ++ QList ciphers = sslContext->sslConfiguration.ciphers(); ++ if (ciphers.isEmpty()) ++ ciphers = QSslSocketPrivate::defaultCiphers(); ++ for (const QSslCipher &cipher : qAsConst(ciphers)) { ++ if (first) ++ first = false; ++ else ++ cipherString.append(':'); ++ cipherString.append(cipher.name().toLatin1()); ++ } ++ ++ if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, cipherString.data())) { ++ sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ ++ const QDateTime now = QDateTime::currentDateTimeUtc(); ++ ++ // Add all our CAs to this store. ++ const auto caCertificates = sslContext->sslConfiguration.caCertificates(); ++ for (const QSslCertificate &caCertificate : caCertificates) { ++ // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html: ++ // ++ // If several CA certificates matching the name, key identifier, and ++ // serial number condition are available, only the first one will be ++ // examined. This may lead to unexpected results if the same CA ++ // certificate is available with different expiration dates. If a ++ // ``certificate expired'' verification error occurs, no other ++ // certificate will be searched. Make sure to not have expired ++ // certificates mixed with valid ones. ++ // ++ // See also: QSslSocketBackendPrivate::verify() ++ if (caCertificate.expiryDate() >= now) { ++ q_X509_STORE_add_cert(q_SSL_CTX_get_cert_store(sslContext->ctx), (X509 *)caCertificate.handle()); ++ } ++ } ++ ++ if (QSslSocketPrivate::s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) { ++ // tell OpenSSL the directories where to look up the root certs on demand ++ const QList unixDirs = QSslSocketPrivate::unixRootCertDirectories(); ++ for (const QByteArray &unixDir : unixDirs) ++ q_SSL_CTX_load_verify_locations(sslContext->ctx, nullptr, unixDir.constData()); ++ } ++ ++ if (!sslContext->sslConfiguration.localCertificate().isNull()) { ++ // Require a private key as well. ++ if (sslContext->sslConfiguration.privateKey().isNull()) { ++ sslContext->errorStr = QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ ++ // Load certificate ++ if (!q_SSL_CTX_use_certificate(sslContext->ctx, (X509 *)sslContext->sslConfiguration.localCertificate().handle())) { ++ sslContext->errorStr = QSslSocket::tr("Error loading local certificate, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ ++ if (configuration.d->privateKey.algorithm() == QSsl::Opaque) { ++ sslContext->pkey = reinterpret_cast(configuration.d->privateKey.handle()); ++ } else { ++ // Load private key ++ sslContext->pkey = q_EVP_PKEY_new(); ++ // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free. ++ // this lead to a memory leak. Now we use the *_set1_* functions which do not ++ // take ownership of the RSA/DSA key instance because the QSslKey already has ownership. ++ if (configuration.d->privateKey.algorithm() == QSsl::Rsa) ++ q_EVP_PKEY_set1_RSA(sslContext->pkey, reinterpret_cast(configuration.d->privateKey.handle())); ++ else if (configuration.d->privateKey.algorithm() == QSsl::Dsa) ++ q_EVP_PKEY_set1_DSA(sslContext->pkey, reinterpret_cast(configuration.d->privateKey.handle())); ++#ifndef OPENSSL_NO_EC ++ else if (configuration.d->privateKey.algorithm() == QSsl::Ec) ++ q_EVP_PKEY_set1_EC_KEY(sslContext->pkey, reinterpret_cast(configuration.d->privateKey.handle())); ++#endif ++ } ++ ++ if (!q_SSL_CTX_use_PrivateKey(sslContext->ctx, sslContext->pkey)) { ++ sslContext->errorStr = QSslSocket::tr("Error loading private key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ if (configuration.d->privateKey.algorithm() == QSsl::Opaque) ++ sslContext->pkey = nullptr; // Don't free the private key, it belongs to QSslKey ++ ++ // Check if the certificate matches the private key. ++ if (!q_SSL_CTX_check_private_key(sslContext->ctx)) { ++ sslContext->errorStr = QSslSocket::tr("Private key does not certify public key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ ++ // If we have any intermediate certificates then we need to add them to our chain ++ bool first = true; ++ for (const QSslCertificate &cert : qAsConst(configuration.d->localCertificateChain)) { ++ if (first) { ++ first = false; ++ continue; ++ } ++ q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, ++ q_X509_dup(reinterpret_cast(cert.handle()))); ++ } ++ } ++ ++ // Initialize peer verification. ++ if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) { ++ q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, nullptr); ++ } else { ++ q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER, q_X509Callback); ++ } ++ ++ // Set verification depth. ++ if (sslContext->sslConfiguration.peerVerifyDepth() != 0) ++ q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth()); ++ ++ // set persisted session if the user set it ++ if (!configuration.sessionTicket().isEmpty()) ++ sslContext->setSessionASN1(configuration.sessionTicket()); ++ ++ // Set temp DH params ++ QSslDiffieHellmanParameters dhparams = configuration.diffieHellmanParameters(); ++ ++ if (!dhparams.isValid()) { ++ sslContext->errorStr = QSslSocket::tr("Diffie-Hellman parameters are not valid"); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ ++ if (!dhparams.isEmpty()) { ++ const QByteArray ¶ms = dhparams.d->derData; ++ const char *ptr = params.constData(); ++ DH *dh = q_d2i_DHparams(NULL, reinterpret_cast(&ptr), params.length()); ++ if (dh == NULL) ++ qFatal("q_d2i_DHparams failed to convert QSslDiffieHellmanParameters to DER form"); ++ q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh); ++ q_DH_free(dh); ++ } ++ ++#ifndef OPENSSL_NO_PSK ++ if (!client) ++ q_SSL_CTX_use_psk_identity_hint(sslContext->ctx, sslContext->sslConfiguration.preSharedKeyIdentityHint().constData()); ++#endif // !OPENSSL_NO_PSK ++ ++ const QVector qcurves = sslContext->sslConfiguration.ellipticCurves(); ++ if (!qcurves.isEmpty()) { ++#ifdef OPENSSL_NO_EC ++ sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("OpenSSL version with disabled elliptic curves")); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++#else ++ // Set the curves to be used. ++ std::vector curves; ++ curves.reserve(qcurves.size()); ++ for (const auto &sslCurve : qcurves) ++ curves.push_back(sslCurve.id); ++ if (!q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_SET_CURVES, long(curves.size()), &curves[0])) { ++ sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ } ++#endif ++ } ++} ++ ++QT_END_NAMESPACE +diff --git a/qtbase/src/network/ssl/qsslcontext_opensslpre11.cpp b/qtbase/src/network/ssl/qsslcontext_opensslpre11.cpp +new file mode 100644 +index 0000000000..9c01c2f2dc +--- /dev/null ++++ b/qtbase/src/network/ssl/qsslcontext_opensslpre11.cpp +@@ -0,0 +1,354 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2017 The Qt Company Ltd. ++** Copyright (C) 2014 BlackBerry Limited. All rights reserved. ++** Copyright (C) 2014 Governikus GmbH & Co. KG. ++** Contact: https://www.qt.io/licensing/ ++** ++** This file is part of the QtNetwork module of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see https://www.qt.io/terms-conditions. For further ++** information use the contact form at https://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 3 as published by the Free Software ++** Foundation and appearing in the file LICENSE.LGPL3 included in the ++** packaging of this file. Please review the following information to ++** ensure the GNU Lesser General Public License version 3 requirements ++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ++** ++** GNU General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU ++** General Public License version 2.0 or (at your option) the GNU General ++** Public license version 3 or any later version approved by the KDE Free ++** Qt Foundation. The licenses are as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ++** included in the packaging of this file. Please review the following ++** information to ensure the GNU General Public License requirements will ++** be met: https://www.gnu.org/licenses/gpl-2.0.html and ++** https://www.gnu.org/licenses/gpl-3.0.html. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++ ++#include ++#include ++ ++#include "private/qssl_p.h" ++#include "private/qsslcontext_openssl_p.h" ++#include "private/qsslsocket_p.h" ++#include "private/qsslsocket_openssl_p.h" ++#include "private/qsslsocket_openssl_symbols_p.h" ++#include "private/qssldiffiehellmanparameters_p.h" ++ ++QT_BEGIN_NAMESPACE ++ ++// defined in qsslsocket_openssl.cpp: ++extern int q_X509Callback(int ok, X509_STORE_CTX *ctx); ++extern QString getErrorsFromOpenSsl(); ++ ++static inline QString msgErrorSettingEllipticCurves(const QString &why) ++{ ++ return QSslSocket::tr("Error when setting the elliptic curves (%1)").arg(why); ++} ++ ++// static ++void QSslContext::initSslContext(QSslContext *sslContext, QSslSocket::SslMode mode, const QSslConfiguration &configuration, bool allowRootCertOnDemandLoading) ++{ ++ sslContext->sslConfiguration = configuration; ++ sslContext->errorCode = QSslError::NoError; ++ ++ bool client = (mode == QSslSocket::SslClientMode); ++ ++ bool reinitialized = false; ++ bool unsupportedProtocol = false; ++init_context: ++ switch (sslContext->sslConfiguration.protocol()) { ++ case QSsl::SslV2: ++#ifndef OPENSSL_NO_SSL2 ++ sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method()); ++#else ++ // SSL 2 not supported by the system, but chosen deliberately -> error ++ sslContext->ctx = 0; ++ unsupportedProtocol = true; ++#endif ++ break; ++ case QSsl::SslV3: ++#ifndef OPENSSL_NO_SSL3_METHOD ++ sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method()); ++#else ++ // SSL 3 not supported by the system, but chosen deliberately -> error ++ sslContext->ctx = 0; ++ unsupportedProtocol = true; ++#endif ++ break; ++ case QSsl::SecureProtocols: ++ // SSLv2 and SSLv3 will be disabled by SSL options ++ // But we need q_SSLv23_server_method() otherwise AnyProtocol will be unable to connect on Win32. ++ case QSsl::TlsV1SslV3: ++ // SSLv2 will will be disabled by SSL options ++ case QSsl::AnyProtocol: ++ default: ++ sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method()); ++ break; ++ case QSsl::TlsV1_0: ++ sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_client_method() : q_TLSv1_server_method()); ++ break; ++ case QSsl::TlsV1_1: ++#if OPENSSL_VERSION_NUMBER >= 0x10001000L ++ sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_1_client_method() : q_TLSv1_1_server_method()); ++#else ++ // TLS 1.1 not supported by the system, but chosen deliberately -> error ++ sslContext->ctx = 0; ++ unsupportedProtocol = true; ++#endif ++ break; ++ case QSsl::TlsV1_2: ++#if OPENSSL_VERSION_NUMBER >= 0x10001000L ++ sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_2_client_method() : q_TLSv1_2_server_method()); ++#else ++ // TLS 1.2 not supported by the system, but chosen deliberately -> error ++ sslContext->ctx = 0; ++ unsupportedProtocol = true; ++#endif ++ break; ++ case QSsl::TlsV1_0OrLater: ++ // Specific protocols will be specified via SSL options. ++ sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method()); ++ break; ++ case QSsl::TlsV1_1OrLater: ++ case QSsl::TlsV1_2OrLater: ++#if OPENSSL_VERSION_NUMBER >= 0x10001000L ++ // Specific protocols will be specified via SSL options. ++ sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv23_client_method() : q_SSLv23_server_method()); ++#else ++ // TLS 1.1/1.2 not supported by the system, but chosen deliberately -> error ++ sslContext->ctx = 0; ++ unsupportedProtocol = true; ++#endif ++ break; ++ } ++ ++ if (!sslContext->ctx) { ++ // After stopping Flash 10 the SSL library loses its ciphers. Try re-adding them ++ // by re-initializing the library. ++ if (!reinitialized) { ++ reinitialized = true; ++ if (q_SSL_library_init() == 1) ++ goto init_context; ++ } ++ ++ sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg( ++ unsupportedProtocol ? QSslSocket::tr("unsupported protocol") : QSslSocketBackendPrivate::getErrorsFromOpenSsl() ++ ); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ ++ // Enable bug workarounds. ++ long options = QSslSocketBackendPrivate::setupOpenSslOptions(configuration.protocol(), configuration.d->sslOptions); ++ q_SSL_CTX_set_options(sslContext->ctx, options); ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10000000L ++ // Tell OpenSSL to release memory early ++ // http://www.openssl.org/docs/ssl/SSL_CTX_set_mode.html ++ if (q_SSLeay() >= 0x10000000L) ++ q_SSL_CTX_set_mode(sslContext->ctx, SSL_MODE_RELEASE_BUFFERS); ++#endif ++ ++ // Initialize ciphers ++ QByteArray cipherString; ++ bool first = true; ++ QList ciphers = sslContext->sslConfiguration.ciphers(); ++ if (ciphers.isEmpty()) ++ ciphers = QSslSocketPrivate::defaultCiphers(); ++ for (const QSslCipher &cipher : qAsConst(ciphers)) { ++ if (first) ++ first = false; ++ else ++ cipherString.append(':'); ++ cipherString.append(cipher.name().toLatin1()); ++ } ++ ++ if (!q_SSL_CTX_set_cipher_list(sslContext->ctx, cipherString.data())) { ++ sslContext->errorStr = QSslSocket::tr("Invalid or empty cipher list (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ ++ const QDateTime now = QDateTime::currentDateTimeUtc(); ++ ++ // Add all our CAs to this store. ++ const auto caCertificates = sslContext->sslConfiguration.caCertificates(); ++ for (const QSslCertificate &caCertificate : caCertificates) { ++ // From https://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html: ++ // ++ // If several CA certificates matching the name, key identifier, and ++ // serial number condition are available, only the first one will be ++ // examined. This may lead to unexpected results if the same CA ++ // certificate is available with different expiration dates. If a ++ // ``certificate expired'' verification error occurs, no other ++ // certificate will be searched. Make sure to not have expired ++ // certificates mixed with valid ones. ++ // ++ // See also: QSslSocketBackendPrivate::verify() ++ if (caCertificate.expiryDate() >= now) { ++ q_X509_STORE_add_cert(q_SSL_CTX_get_cert_store(sslContext->ctx), (X509 *)caCertificate.handle()); ++ } ++ } ++ ++ if (QSslSocketPrivate::s_loadRootCertsOnDemand && allowRootCertOnDemandLoading) { ++ // tell OpenSSL the directories where to look up the root certs on demand ++ const QList unixDirs = QSslSocketPrivate::unixRootCertDirectories(); ++ for (const QByteArray &unixDir : unixDirs) ++ q_SSL_CTX_load_verify_locations(sslContext->ctx, 0, unixDir.constData()); ++ } ++ ++ if (!sslContext->sslConfiguration.localCertificate().isNull()) { ++ // Require a private key as well. ++ if (sslContext->sslConfiguration.privateKey().isNull()) { ++ sslContext->errorStr = QSslSocket::tr("Cannot provide a certificate with no key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ ++ // Load certificate ++ if (!q_SSL_CTX_use_certificate(sslContext->ctx, (X509 *)sslContext->sslConfiguration.localCertificate().handle())) { ++ sslContext->errorStr = QSslSocket::tr("Error loading local certificate, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ ++ if (configuration.d->privateKey.algorithm() == QSsl::Opaque) { ++ sslContext->pkey = reinterpret_cast(configuration.d->privateKey.handle()); ++ } else { ++ // Load private key ++ sslContext->pkey = q_EVP_PKEY_new(); ++ // before we were using EVP_PKEY_assign_R* functions and did not use EVP_PKEY_free. ++ // this lead to a memory leak. Now we use the *_set1_* functions which do not ++ // take ownership of the RSA/DSA key instance because the QSslKey already has ownership. ++ if (configuration.d->privateKey.algorithm() == QSsl::Rsa) ++ q_EVP_PKEY_set1_RSA(sslContext->pkey, reinterpret_cast(configuration.d->privateKey.handle())); ++ else if (configuration.d->privateKey.algorithm() == QSsl::Dsa) ++ q_EVP_PKEY_set1_DSA(sslContext->pkey, reinterpret_cast(configuration.d->privateKey.handle())); ++#ifndef OPENSSL_NO_EC ++ else if (configuration.d->privateKey.algorithm() == QSsl::Ec) ++ q_EVP_PKEY_set1_EC_KEY(sslContext->pkey, reinterpret_cast(configuration.d->privateKey.handle())); ++#endif ++ } ++ ++ if (!q_SSL_CTX_use_PrivateKey(sslContext->ctx, sslContext->pkey)) { ++ sslContext->errorStr = QSslSocket::tr("Error loading private key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ if (configuration.d->privateKey.algorithm() == QSsl::Opaque) ++ sslContext->pkey = 0; // Don't free the private key, it belongs to QSslKey ++ ++ // Check if the certificate matches the private key. ++ if (!q_SSL_CTX_check_private_key(sslContext->ctx)) { ++ sslContext->errorStr = QSslSocket::tr("Private key does not certify public key, %1").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ ++ // If we have any intermediate certificates then we need to add them to our chain ++ bool first = true; ++ for (const QSslCertificate &cert : qAsConst(configuration.d->localCertificateChain)) { ++ if (first) { ++ first = false; ++ continue; ++ } ++ q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, ++ q_X509_dup(reinterpret_cast(cert.handle()))); ++ } ++ } ++ ++ // Initialize peer verification. ++ if (sslContext->sslConfiguration.peerVerifyMode() == QSslSocket::VerifyNone) { ++ q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_NONE, 0); ++ } else { ++ q_SSL_CTX_set_verify(sslContext->ctx, SSL_VERIFY_PEER, q_X509Callback); ++ } ++ ++ // Set verification depth. ++ if (sslContext->sslConfiguration.peerVerifyDepth() != 0) ++ q_SSL_CTX_set_verify_depth(sslContext->ctx, sslContext->sslConfiguration.peerVerifyDepth()); ++ ++ // set persisted session if the user set it ++ if (!configuration.sessionTicket().isEmpty()) ++ sslContext->setSessionASN1(configuration.sessionTicket()); ++ ++ // Set temp DH params ++ QSslDiffieHellmanParameters dhparams = configuration.diffieHellmanParameters(); ++ ++ if (!dhparams.isValid()) { ++ sslContext->errorStr = QSslSocket::tr("Diffie-Hellman parameters are not valid"); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ return; ++ } ++ ++ if (!dhparams.isEmpty()) { ++ const QByteArray ¶ms = dhparams.d->derData; ++ const char *ptr = params.constData(); ++ DH *dh = q_d2i_DHparams(NULL, reinterpret_cast(&ptr), params.length()); ++ if (dh == NULL) ++ qFatal("q_d2i_DHparams failed to convert QSslDiffieHellmanParameters to DER form"); ++ q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh); ++ q_DH_free(dh); ++ } ++ ++#ifndef OPENSSL_NO_EC ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L ++ if (q_SSLeay() >= 0x10002000L) { ++ q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL); ++ } else ++#endif ++ { ++ // Set temp ECDH params ++ EC_KEY *ecdh = 0; ++ ecdh = q_EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ++ q_SSL_CTX_set_tmp_ecdh(sslContext->ctx, ecdh); ++ q_EC_KEY_free(ecdh); ++ } ++#endif // OPENSSL_NO_EC ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK) ++ if (!client) ++ q_SSL_CTX_use_psk_identity_hint(sslContext->ctx, sslContext->sslConfiguration.preSharedKeyIdentityHint().constData()); ++#endif // OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK) ++ ++ const QVector qcurves = sslContext->sslConfiguration.ellipticCurves(); ++ if (!qcurves.isEmpty()) { ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC) ++ // Set the curves to be used ++ if (q_SSLeay() >= 0x10002000L) { ++ // SSL_CTX_ctrl wants a non-const pointer as last argument, ++ // but let's avoid a copy into a temporary array ++ if (!q_SSL_CTX_ctrl(sslContext->ctx, ++ SSL_CTRL_SET_CURVES, ++ qcurves.size(), ++ const_cast(reinterpret_cast(qcurves.data())))) { ++ sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ } ++ } else ++#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(OPENSSL_NO_EC) ++ { ++ // specific curves requested, but not possible to set -> error ++ sslContext->errorStr = msgErrorSettingEllipticCurves(QSslSocket::tr("OpenSSL version too old, need at least v1.0.2")); ++ sslContext->errorCode = QSslError::UnspecifiedError; ++ } ++ } ++} ++ ++QT_END_NAMESPACE +diff --git a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp +index 90687b05c5..5ebad822f1 100644 +--- a/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp ++++ b/qtbase/src/network/ssl/qssldiffiehellmanparameters_openssl.cpp +@@ -1,6 +1,7 @@ + /**************************************************************************** + ** + ** Copyright (C) 2015 Mikkel Krautz ++** Copyright (C) 2016 Richard J. Moore + ** Contact: https://www.qt.io/licensing/ + ** + ** This file is part of the QtNetwork module of the Qt Toolkit. +@@ -50,8 +51,8 @@ + #include + #endif + +-// For q_BN_is_word. + #include ++#include + + QT_BEGIN_NAMESPACE + +@@ -62,13 +63,6 @@ static bool isSafeDH(DH *dh) + + QSslSocketPrivate::ensureInitialized(); + +- // Mark p < 1024 bits as unsafe. +- if (q_BN_num_bits(dh->p) < 1024) { +- return false; +- } +- +- if (q_DH_check(dh, &status) != 1) +- return false; + + // From https://wiki.openssl.org/index.php/Diffie-Hellman_parameters: + // +@@ -81,11 +75,39 @@ static bool isSafeDH(DH *dh) + // Without the test, the IETF parameters would + // fail validation. For details, see Diffie-Hellman + // Parameter Check (when g = 2, must p mod 24 == 11?). ++#if QT_CONFIG(opensslv11) ++ // Mark p < 1024 bits as unsafe. ++ if (q_DH_bits(dh) < 1024) ++ return false; ++ ++ if (q_DH_check(dh, &status) != 1) ++ return false; ++ ++ const BIGNUM *p = nullptr; ++ const BIGNUM *q = nullptr; ++ const BIGNUM *g = nullptr; ++ q_DH_get0_pqg(dh, &p, &q, &g); ++ ++ if (q_BN_is_word(const_cast(g), DH_GENERATOR_2)) { ++ long residue = q_BN_mod_word(p, 24); ++ if (residue == 11 || residue == 23) ++ status &= ~DH_NOT_SUITABLE_GENERATOR; ++ } ++ ++#else ++ // Mark p < 1024 bits as unsafe. ++ if (q_BN_num_bits(dh->p) < 1024) ++ return false; ++ ++ if (q_DH_check(dh, &status) != 1) ++ return false; ++ + if (q_BN_is_word(dh->g, DH_GENERATOR_2)) { + long residue = q_BN_mod_word(dh->p, 24); + if (residue == 11 || residue == 23) + status &= ~DH_NOT_SUITABLE_GENERATOR; + } ++#endif + + bad |= DH_CHECK_P_NOT_PRIME; + bad |= DH_CHECK_P_NOT_SAFE_PRIME; +diff --git a/qtbase/src/network/ssl/qsslellipticcurve.h b/qtbase/src/network/ssl/qsslellipticcurve.h +index 231566063e..57dda19bad 100644 +--- a/qtbase/src/network/ssl/qsslellipticcurve.h ++++ b/qtbase/src/network/ssl/qsslellipticcurve.h +@@ -80,6 +80,7 @@ private: + friend Q_DECL_CONSTEXPR bool operator==(QSslEllipticCurve lhs, QSslEllipticCurve rhs) Q_DECL_NOTHROW; + friend Q_DECL_CONSTEXPR uint qHash(QSslEllipticCurve curve, uint seed) Q_DECL_NOTHROW; + ++ friend class QSslContext; + friend class QSslSocketPrivate; + friend class QSslSocketBackendPrivate; + }; +diff --git a/qtbase/src/network/ssl/qsslellipticcurve_openssl.cpp b/qtbase/src/network/ssl/qsslellipticcurve_openssl.cpp +index e18197b703..8cd14837f0 100644 +--- a/qtbase/src/network/ssl/qsslellipticcurve_openssl.cpp ++++ b/qtbase/src/network/ssl/qsslellipticcurve_openssl.cpp +@@ -1,6 +1,7 @@ + /**************************************************************************** + ** + ** Copyright (C) 2014 Governikus GmbH & Co. KG. ++** Copyright (C) 2016 Richard J. Moore + ** Contact: https://www.qt.io/licensing/ + ** + ** This file is part of the QtNetwork module of the Qt Toolkit. +@@ -78,17 +79,18 @@ QSslEllipticCurve QSslEllipticCurve::fromShortName(const QString &name) + QSslEllipticCurve result; + + #ifndef OPENSSL_NO_EC +- const QByteArray curveNameLatin1 = name.toLatin1(); + ++ const QByteArray curveNameLatin1 = name.toLatin1(); + int nid = q_OBJ_sn2nid(curveNameLatin1.data()); + + #if OPENSSL_VERSION_NUMBER >= 0x10002000L +- if (nid == 0 && q_SSLeay() >= 0x10002000L) ++ if (nid == 0 && QSslSocket::sslLibraryVersionNumber() >= 0x10002000L) + nid = q_EC_curve_nist2nid(curveNameLatin1.data()); + #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L + + result.id = nid; +-#endif ++ ++#endif // !OPENSSL_NO_EC + + return result; + } +diff --git a/qtbase/src/network/ssl/qsslkey_openssl.cpp b/qtbase/src/network/ssl/qsslkey_openssl.cpp +index 26119023d1..2b03af9441 100644 +--- a/qtbase/src/network/ssl/qsslkey_openssl.cpp ++++ b/qtbase/src/network/ssl/qsslkey_openssl.cpp +@@ -1,6 +1,7 @@ + /**************************************************************************** + ** +-** Copyright (C) 2016 The Qt Company Ltd. ++** Copyright (C) 2017 The Qt Company Ltd. ++** Copyright (C) 2016 Richard J. Moore + ** Contact: https://www.qt.io/licensing/ + ** + ** This file is part of the QtNetwork module of the Qt Toolkit. +@@ -87,33 +88,32 @@ bool QSslKeyPrivate::fromEVP_PKEY(EVP_PKEY *pkey) + if (pkey == nullptr) + return false; + +- if (pkey->type == EVP_PKEY_RSA) { ++#if QT_CONFIG(opensslv11) ++ const int keyType = q_EVP_PKEY_type(q_EVP_PKEY_base_id(pkey)); ++#else ++ const int keyType = pkey->type; ++#endif ++ if (keyType == EVP_PKEY_RSA) { + isNull = false; + algorithm = QSsl::Rsa; + type = QSsl::PrivateKey; + +- rsa = q_RSA_new(); +- memcpy(rsa, q_EVP_PKEY_get1_RSA(pkey), sizeof(RSA)); +- ++ rsa = q_EVP_PKEY_get1_RSA(pkey); + return true; +- } +- else if (pkey->type == EVP_PKEY_DSA) { ++ } else if (keyType == EVP_PKEY_DSA) { + isNull = false; + algorithm = QSsl::Dsa; + type = QSsl::PrivateKey; + +- dsa = q_DSA_new(); +- memcpy(dsa, q_EVP_PKEY_get1_DSA(pkey), sizeof(DSA)); +- ++ dsa = q_EVP_PKEY_get1_DSA(pkey); + return true; + } + #ifndef OPENSSL_NO_EC +- else if (pkey->type == EVP_PKEY_EC) { ++ else if (keyType == EVP_PKEY_EC) { + isNull = false; + algorithm = QSsl::Ec; + type = QSsl::PrivateKey; +- ec = q_EC_KEY_dup(q_EVP_PKEY_get1_EC_KEY(pkey)); +- ++ ec = q_EVP_PKEY_get1_EC_KEY(pkey); + return true; + } + #endif +@@ -181,8 +181,8 @@ int QSslKeyPrivate::length() const + return -1; + + switch (algorithm) { +- case QSsl::Rsa: return q_BN_num_bits(rsa->n); +- case QSsl::Dsa: return q_BN_num_bits(dsa->p); ++ case QSsl::Rsa: return q_RSA_bits(rsa); ++ case QSsl::Dsa: return q_DSA_bits(dsa); + #ifndef OPENSSL_NO_EC + case QSsl::Ec: return q_EC_GROUP_get_degree(q_EC_KEY_get0_group(ec)); + #endif +@@ -276,7 +276,13 @@ Qt::HANDLE QSslKeyPrivate::handle() const + + static QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv, int enc) + { +- EVP_CIPHER_CTX ctx; ++#if QT_CONFIG(opensslv11) ++ EVP_CIPHER_CTX *ctx = q_EVP_CIPHER_CTX_new(); ++#else ++ EVP_CIPHER_CTX evpCipherContext; ++ EVP_CIPHER_CTX *ctx = &evpCipherContext; ++#endif ++ + const EVP_CIPHER* type = 0; + int i = 0, len = 0; + +@@ -294,21 +300,44 @@ static QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, const QByteArray &data, + + QByteArray output; + output.resize(data.size() + EVP_MAX_BLOCK_LENGTH); +- q_EVP_CIPHER_CTX_init(&ctx); +- q_EVP_CipherInit(&ctx, type, NULL, NULL, enc); +- q_EVP_CIPHER_CTX_set_key_length(&ctx, key.size()); ++ ++#if QT_CONFIG(opensslv11) ++ q_EVP_CIPHER_CTX_reset(ctx); ++#else ++ q_EVP_CIPHER_CTX_init(ctx); ++#endif ++ ++ q_EVP_CipherInit(ctx, type, NULL, NULL, enc); ++ q_EVP_CIPHER_CTX_set_key_length(ctx, key.size()); + if (cipher == QSslKeyPrivate::Rc2Cbc) +- q_EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_SET_RC2_KEY_BITS, 8 * key.size(), NULL); +- q_EVP_CipherInit(&ctx, NULL, ++ q_EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, 8 * key.size(), NULL); ++ ++#if QT_CONFIG(opensslv11) ++ // EVP_CipherInit in 1.1 resets the context thus making the calls above useless. ++ // We call EVP_CipherInit_ex instead. ++ q_EVP_CipherInit_ex(ctx, nullptr, nullptr, ++ reinterpret_cast(key.constData()), ++ reinterpret_cast(iv.constData()), ++ enc); ++#else ++ q_EVP_CipherInit(ctx, NULL, + reinterpret_cast(key.constData()), + reinterpret_cast(iv.constData()), enc); +- q_EVP_CipherUpdate(&ctx, ++#endif // opensslv11 ++ ++ q_EVP_CipherUpdate(ctx, + reinterpret_cast(output.data()), &len, + reinterpret_cast(data.constData()), data.size()); +- q_EVP_CipherFinal(&ctx, ++ q_EVP_CipherFinal(ctx, + reinterpret_cast(output.data()) + len, &i); + len += i; +- q_EVP_CIPHER_CTX_cleanup(&ctx); ++ ++#if QT_CONFIG(opensslv11) ++ q_EVP_CIPHER_CTX_reset(ctx); ++ q_EVP_CIPHER_CTX_free(ctx); ++#else ++ q_EVP_CIPHER_CTX_cleanup(ctx); ++#endif + + return output.left(len); + } +diff --git a/qtbase/src/network/ssl/qsslsocket_openssl.cpp b/qtbase/src/network/ssl/qsslsocket_openssl.cpp +index f5b493897e..45cea490fc 100644 +--- a/qtbase/src/network/ssl/qsslsocket_openssl.cpp ++++ b/qtbase/src/network/ssl/qsslsocket_openssl.cpp +@@ -1,6 +1,6 @@ + /**************************************************************************** + ** +-** Copyright (C) 2016 The Qt Company Ltd. ++** Copyright (C) 2017 The Qt Company Ltd. + ** Copyright (C) 2014 Governikus GmbH & Co. KG + ** Contact: https://www.qt.io/licensing/ + ** +@@ -97,70 +97,6 @@ bool QSslSocketPrivate::s_loadRootCertsOnDemand = false; + int QSslSocketBackendPrivate::s_indexForSSLExtraData = -1; + #endif + +-/* \internal +- +- From OpenSSL's thread(3) manual page: +- +- OpenSSL can safely be used in multi-threaded applications provided that at +- least two callback functions are set. +- +- locking_function(int mode, int n, const char *file, int line) is needed to +- perform locking on shared data structures. (Note that OpenSSL uses a +- number of global data structures that will be implicitly shared +- whenever multiple threads use OpenSSL.) Multi-threaded +- applications will crash at random if it is not set. ... +- ... +- id_function(void) is a function that returns a thread ID. It is not +- needed on Windows nor on platforms where getpid() returns a different +- ID for each thread (most notably Linux) +-*/ +-class QOpenSslLocks +-{ +-public: +- inline QOpenSslLocks() +- : initLocker(QMutex::Recursive), +- locksLocker(QMutex::Recursive) +- { +- QMutexLocker locker(&locksLocker); +- int numLocks = q_CRYPTO_num_locks(); +- locks = new QMutex *[numLocks]; +- memset(locks, 0, numLocks * sizeof(QMutex *)); +- } +- inline ~QOpenSslLocks() +- { +- QMutexLocker locker(&locksLocker); +- for (int i = 0; i < q_CRYPTO_num_locks(); ++i) +- delete locks[i]; +- delete [] locks; +- +- QSslSocketPrivate::deinitialize(); +- } +- inline QMutex *lock(int num) +- { +- QMutexLocker locker(&locksLocker); +- QMutex *tmp = locks[num]; +- if (!tmp) +- tmp = locks[num] = new QMutex(QMutex::Recursive); +- return tmp; +- } +- +- QMutex *globalLock() +- { +- return &locksLocker; +- } +- +- QMutex *initLock() +- { +- return &initLocker; +- } +- +-private: +- QMutex initLocker; +- QMutex locksLocker; +- QMutex **locks; +-}; +-Q_GLOBAL_STATIC(QOpenSslLocks, openssl_locks) +- + QString QSslSocketBackendPrivate::getErrorsFromOpenSsl() + { + QString errorString; +@@ -175,20 +111,6 @@ QString QSslSocketBackendPrivate::getErrorsFromOpenSsl() + } + + extern "C" { +-static void locking_function(int mode, int lockNumber, const char *, int) +-{ +- QMutex *mutex = openssl_locks()->lock(lockNumber); +- +- // Lock or unlock it +- if (mode & CRYPTO_LOCK) +- mutex->lock(); +- else +- mutex->unlock(); +-} +-static unsigned long id_function() +-{ +- return (quintptr)QThread::currentThreadId(); +-} + + #if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK) + static unsigned int q_ssl_psk_client_callback(SSL *ssl, +@@ -227,7 +149,7 @@ QSslSocketBackendPrivate::~QSslSocketBackendPrivate() + destroySslContext(); + } + +-QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(SSL_CIPHER *cipher) ++QSslCipher QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher) + { + QSslCipher ciph; + +@@ -283,6 +205,7 @@ struct QSslErrorList + QMutex mutex; + QVector errors; + }; ++ + Q_GLOBAL_STATIC(QSslErrorList, _q_sslErrorList) + + int q_X509Callback(int ok, X509_STORE_CTX *ctx) +@@ -312,7 +235,7 @@ int q_X509Callback(int ok, X509_STORE_CTX *ctx) + } + #endif + } +- // Always return OK to allow verification to continue. We're handle the ++ // Always return OK to allow verification to continue. We handle the + // errors gracefully after collecting all errors, after verification has + // completed. + return 1; +@@ -397,7 +320,7 @@ bool QSslSocketBackendPrivate::initSslContext() + if (configuration.protocol != QSsl::SslV2 && + configuration.protocol != QSsl::SslV3 && + configuration.protocol != QSsl::UnknownProtocol && +- mode == QSslSocket::SslClientMode && q_SSLeay() >= 0x00090806fL) { ++ mode == QSslSocket::SslClientMode && QSslSocket::sslLibraryVersionNumber() >= 0x00090806fL) { + // Set server hostname on TLS extension. RFC4366 section 3.1 requires it in ACE format. + QString tlsHostName = verificationPeerName.isEmpty() ? q->peerName() : verificationPeerName; + if (tlsHostName.isEmpty()) +@@ -438,13 +361,13 @@ bool QSslSocketBackendPrivate::initSslContext() + + #if OPENSSL_VERSION_NUMBER >= 0x10001000L + // Save a pointer to this object into the SSL structure. +- if (q_SSLeay() >= 0x10001000L) ++ if (QSslSocket::sslLibraryVersionNumber() >= 0x10001000L) + q_SSL_set_ex_data(ssl, s_indexForSSLExtraData, this); + #endif + + #if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK) + // Set the client callback for PSK +- if (q_SSLeay() >= 0x10001000L) { ++ if (QSslSocket::sslLibraryVersionNumber() >= 0x10001000L) { + if (mode == QSslSocket::SslClientMode) + q_SSL_set_psk_client_callback(ssl, &q_ssl_psk_client_callback); + else if (mode == QSslSocket::SslServerMode) +@@ -464,16 +387,6 @@ void QSslSocketBackendPrivate::destroySslContext() + sslContextPointer.clear(); + } + +-/*! +- \internal +-*/ +-void QSslSocketPrivate::deinitialize() +-{ +- q_CRYPTO_set_id_callback(0); +- q_CRYPTO_set_locking_callback(0); +- q_ERR_free_strings(); +-} +- + /*! + \internal + +@@ -486,91 +399,6 @@ bool QSslSocketPrivate::supportsSsl() + return ensureLibraryLoaded(); + } + +-bool QSslSocketPrivate::ensureLibraryLoaded() +-{ +- if (!q_resolveOpenSslSymbols()) +- return false; +- +- // Check if the library itself needs to be initialized. +- QMutexLocker locker(openssl_locks()->initLock()); +- +- if (!s_libraryLoaded) { +- s_libraryLoaded = true; +- +- // Initialize OpenSSL. +- q_CRYPTO_set_id_callback(id_function); +- q_CRYPTO_set_locking_callback(locking_function); +- if (q_SSL_library_init() != 1) +- return false; +- q_SSL_load_error_strings(); +- q_OpenSSL_add_all_algorithms(); +- +-#if OPENSSL_VERSION_NUMBER >= 0x10001000L +- if (q_SSLeay() >= 0x10001000L) +- QSslSocketBackendPrivate::s_indexForSSLExtraData = q_SSL_get_ex_new_index(0L, NULL, NULL, NULL, NULL); +-#endif +- +- // Initialize OpenSSL's random seed. +- if (!q_RAND_status()) { +- qWarning("Random number generator not seeded, disabling SSL support"); +- return false; +- } +- } +- return true; +-} +- +-void QSslSocketPrivate::ensureCiphersAndCertsLoaded() +-{ +- QMutexLocker locker(openssl_locks()->initLock()); +- if (s_loadedCiphersAndCerts) +- return; +- s_loadedCiphersAndCerts = true; +- +- resetDefaultCiphers(); +- resetDefaultEllipticCurves(); +- +-#if QT_CONFIG(library) +- //load symbols needed to receive certificates from system store +-#if defined(Q_OS_WIN) +- HINSTANCE hLib = LoadLibraryW(L"Crypt32"); +- if (hLib) { +- ptrCertOpenSystemStoreW = (PtrCertOpenSystemStoreW)GetProcAddress(hLib, "CertOpenSystemStoreW"); +- ptrCertFindCertificateInStore = (PtrCertFindCertificateInStore)GetProcAddress(hLib, "CertFindCertificateInStore"); +- ptrCertCloseStore = (PtrCertCloseStore)GetProcAddress(hLib, "CertCloseStore"); +- if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore) +- qCWarning(lcSsl, "could not resolve symbols in crypt32 library"); // should never happen +- } else { +- qCWarning(lcSsl, "could not load crypt32 library"); // should never happen +- } +-#elif defined(Q_OS_QNX) +- s_loadRootCertsOnDemand = true; +-#elif defined(Q_OS_UNIX) && !defined(Q_OS_MAC) +- // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there) +- QList dirs = unixRootCertDirectories(); +- QStringList symLinkFilter; +- symLinkFilter << QLatin1String("[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]"); +- for (int a = 0; a < dirs.count(); ++a) { +- QDirIterator iterator(QLatin1String(dirs.at(a)), symLinkFilter, QDir::Files); +- if (iterator.hasNext()) { +- s_loadRootCertsOnDemand = true; +- break; +- } +- } +-#endif +-#endif // QT_CONFIG(library) +- // if on-demand loading was not enabled, load the certs now +- if (!s_loadRootCertsOnDemand) +- setDefaultCaCertificates(systemCaCertificates()); +-#ifdef Q_OS_WIN +- //Enabled for fetching additional root certs from windows update on windows 6+ +- //This flag is set false by setDefaultCaCertificates() indicating the app uses +- //its own cert bundle rather than the system one. +- //Same logic that disables the unix on demand cert loading. +- //Unlike unix, we do preload the certificates from the cert store. +- if ((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) >= QSysInfo::WV_6_0) +- s_loadRootCertsOnDemand = true; +-#endif +-} + + /*! + \internal +@@ -587,26 +415,6 @@ void QSslSocketPrivate::ensureInitialized() + ensureCiphersAndCertsLoaded(); + } + +-long QSslSocketPrivate::sslLibraryVersionNumber() +-{ +- if (!supportsSsl()) +- return 0; +- +- return q_SSLeay(); +-} +- +-QString QSslSocketPrivate::sslLibraryVersionString() +-{ +- if (!supportsSsl()) +- return QString(); +- +- const char *versionString = q_SSLeay_version(SSLEAY_VERSION); +- if (!versionString) +- return QString(); +- +- return QString::fromLatin1(versionString); +-} +- + long QSslSocketPrivate::sslLibraryBuildVersionNumber() + { + return OPENSSL_VERSION_NUMBER; +@@ -628,7 +436,11 @@ QString QSslSocketPrivate::sslLibraryBuildVersionString() + */ + void QSslSocketPrivate::resetDefaultCiphers() + { ++#if QT_CONFIG(opensslv11) ++ SSL_CTX *myCtx = q_SSL_CTX_new(q_TLS_client_method()); ++#else + SSL_CTX *myCtx = q_SSL_CTX_new(q_SSLv23_client_method()); ++#endif + SSL *mySsl = q_SSL_new(myCtx); + + QList ciphers; +@@ -664,7 +476,7 @@ void QSslSocketPrivate::resetDefaultEllipticCurves() + QVector curves; + + #ifndef OPENSSL_NO_EC +- const size_t curveCount = q_EC_get_builtin_curves(NULL, 0); ++ const size_t curveCount = q_EC_get_builtin_curves(nullptr, 0); + + QVarLengthArray builtinCurves(static_cast(curveCount)); + +@@ -698,13 +510,14 @@ QList QSslSocketPrivate::systemCaCertificates() + if (ptrCertOpenSystemStoreW && ptrCertFindCertificateInStore && ptrCertCloseStore) { + HCERTSTORE hSystemStore; + hSystemStore = ptrCertOpenSystemStoreW(0, L"ROOT"); +- if(hSystemStore) { +- PCCERT_CONTEXT pc = NULL; +- while(1) { +- pc = ptrCertFindCertificateInStore( hSystemStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, pc); +- if(!pc) ++ if (hSystemStore) { ++ PCCERT_CONTEXT pc = nullptr; ++ while (1) { ++ pc = ptrCertFindCertificateInStore(hSystemStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, nullptr, pc); ++ if (!pc) + break; +- QByteArray der((const char *)(pc->pbCertEncoded), static_cast(pc->cbCertEncoded)); ++ QByteArray der(reinterpret_cast(pc->pbCertEncoded), ++ static_cast(pc->cbCertEncoded)); + QSslCertificate cert(der, QSsl::Der); + systemCerts.append(cert); + } +@@ -1504,14 +1317,8 @@ QSslCipher QSslSocketBackendPrivate::sessionCipher() const + { + if (!ssl) + return QSslCipher(); +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L +- // FIXME This is fairly evil, but needed to keep source level compatibility +- // with the OpenSSL 0.9.x implementation at maximum -- some other functions +- // don't take a const SSL_CIPHER* when they should +- SSL_CIPHER *sessionCipher = const_cast(q_SSL_get_current_cipher(ssl)); +-#else +- SSL_CIPHER *sessionCipher = q_SSL_get_current_cipher(ssl); +-#endif ++ ++ const SSL_CIPHER *sessionCipher = q_SSL_get_current_cipher(ssl); + return sessionCipher ? QSslCipher_from_SSL_CIPHER(sessionCipher) : QSslCipher(); + } + +@@ -1537,112 +1344,6 @@ QSsl::SslProtocol QSslSocketBackendPrivate::sessionProtocol() const + return QSsl::UnknownProtocol; + } + +-void QSslSocketBackendPrivate::continueHandshake() +-{ +- Q_Q(QSslSocket); +- // if we have a max read buffer size, reset the plain socket's to match +- if (readBufferMaxSize) +- plainSocket->setReadBufferSize(readBufferMaxSize); +- +- if (q_SSL_ctrl((ssl), SSL_CTRL_GET_SESSION_REUSED, 0, NULL)) +- configuration.peerSessionShared = true; +- +-#ifdef QT_DECRYPT_SSL_TRAFFIC +- if (ssl->session && ssl->s3) { +- const char *mk = reinterpret_cast(ssl->session->master_key); +- QByteArray masterKey(mk, ssl->session->master_key_length); +- const char *random = reinterpret_cast(ssl->s3->client_random); +- QByteArray clientRandom(random, SSL3_RANDOM_SIZE); +- +- // different format, needed for e.g. older Wireshark versions: +-// const char *sid = reinterpret_cast(ssl->session->session_id); +-// QByteArray sessionID(sid, ssl->session->session_id_length); +-// QByteArray debugLineRSA("RSA Session-ID:"); +-// debugLineRSA.append(sessionID.toHex().toUpper()); +-// debugLineRSA.append(" Master-Key:"); +-// debugLineRSA.append(masterKey.toHex().toUpper()); +-// debugLineRSA.append("\n"); +- +- QByteArray debugLineClientRandom("CLIENT_RANDOM "); +- debugLineClientRandom.append(clientRandom.toHex().toUpper()); +- debugLineClientRandom.append(" "); +- debugLineClientRandom.append(masterKey.toHex().toUpper()); +- debugLineClientRandom.append("\n"); +- +- QString sslKeyFile = QDir::tempPath() + QLatin1String("/qt-ssl-keys"); +- QFile file(sslKeyFile); +- if (!file.open(QIODevice::Append)) +- qCWarning(lcSsl) << "could not open file" << sslKeyFile << "for appending"; +- if (!file.write(debugLineClientRandom)) +- qCWarning(lcSsl) << "could not write to file" << sslKeyFile; +- file.close(); +- } else { +- qCWarning(lcSsl, "could not decrypt SSL traffic"); +- } +-#endif +- +- // Cache this SSL session inside the QSslContext +- if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionSharing)) { +- if (!sslContextPointer->cacheSession(ssl)) { +- sslContextPointer.clear(); // we could not cache the session +- } else { +- // Cache the session for permanent usage as well +- if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionPersistence)) { +- if (!sslContextPointer->sessionASN1().isEmpty()) +- configuration.sslSession = sslContextPointer->sessionASN1(); +- configuration.sslSessionTicketLifeTimeHint = sslContextPointer->sessionTicketLifeTimeHint(); +- } +- } +- } +- +-#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG) +- +- configuration.nextProtocolNegotiationStatus = sslContextPointer->npnContext().status; +- if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) { +- // we could not agree -> be conservative and use HTTP/1.1 +- configuration.nextNegotiatedProtocol = QByteArrayLiteral("http/1.1"); +- } else { +- const unsigned char *proto = 0; +- unsigned int proto_len = 0; +-#if OPENSSL_VERSION_NUMBER >= 0x10002000L +- if (q_SSLeay() >= 0x10002000L) { +- q_SSL_get0_alpn_selected(ssl, &proto, &proto_len); +- if (proto_len && mode == QSslSocket::SslClientMode) { +- // Client does not have a callback that sets it ... +- configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNegotiated; +- } +- } +- +- if (!proto_len) { // Test if NPN was more lucky ... +-#else +- { +-#endif +- q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len); +- } +- +- if (proto_len) +- configuration.nextNegotiatedProtocol = QByteArray(reinterpret_cast(proto), proto_len); +- else +- configuration.nextNegotiatedProtocol.clear(); +- } +-#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ... +- +-#if OPENSSL_VERSION_NUMBER >= 0x10002000L +- if (q_SSLeay() >= 0x10002000L && mode == QSslSocket::SslClientMode) { +- EVP_PKEY *key; +- if (q_SSL_get_server_tmp_key(ssl, &key)) +- configuration.ephemeralServerKey = QSslKey(key, QSsl::PublicKey); +- } +-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ... +- +- connectionEncrypted = true; +- emit q->encrypted(); +- if (autoStartHandshake && pendingClose) { +- pendingClose = false; +- q->disconnectFromHost(); +- } +-} +- + QList QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509) + { + ensureInitialized(); +@@ -1696,12 +1397,12 @@ QList QSslSocketBackendPrivate::verify(const QList & + QMutexLocker sslErrorListMutexLocker(&_q_sslErrorList()->mutex); + + // Register a custom callback to get all verification errors. +- X509_STORE_set_verify_cb_func(certStore, q_X509Callback); ++ q_X509_STORE_set_verify_cb(certStore, q_X509Callback); + + // Build the chain of intermediate certificates + STACK_OF(X509) *intermediates = 0; + if (certificateChain.length() > 1) { +- intermediates = (STACK_OF(X509) *) q_sk_new_null(); ++ intermediates = (STACK_OF(X509) *) q_OPENSSL_sk_new_null(); + + if (!intermediates) { + q_X509_STORE_free(certStore); +@@ -1715,11 +1416,8 @@ QList QSslSocketBackendPrivate::verify(const QList & + first = false; + continue; + } +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L +- q_sk_push( (_STACK *)intermediates, reinterpret_cast(cert.handle())); +-#else +- q_sk_push( (STACK *)intermediates, reinterpret_cast(cert.handle())); +-#endif ++ ++ q_OPENSSL_sk_push((OPENSSL_STACK *)intermediates, reinterpret_cast(cert.handle())); + } + } + +@@ -1743,11 +1441,7 @@ QList QSslSocketBackendPrivate::verify(const QList & + (void) q_X509_verify_cert(storeContext); + + q_X509_STORE_CTX_free(storeContext); +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L +- q_sk_free( (_STACK *) intermediates); +-#else +- q_sk_free( (STACK *) intermediates); +-#endif ++ q_OPENSSL_sk_free((OPENSSL_STACK *)intermediates); + + // Now process the errors + const auto errorList = std::move(_q_sslErrorList()->errors); +@@ -1821,7 +1515,8 @@ bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device, + // Convert to Qt types + if (!key->d->fromEVP_PKEY(pkey)) { + qCWarning(lcSsl, "Unable to convert private key"); +- q_sk_pop_free(reinterpret_cast(ca), reinterpret_cast(q_sk_free)); ++ q_OPENSSL_sk_pop_free(reinterpret_cast(ca), ++ reinterpret_cast(q_OPENSSL_sk_free)); + q_X509_free(x509); + q_EVP_PKEY_free(pkey); + q_PKCS12_free(p12); +@@ -1836,7 +1531,11 @@ bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device, + *caCertificates = QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(ca); + + // Clean up +- q_sk_pop_free(reinterpret_cast(ca), reinterpret_cast(q_sk_free)); ++ // TODO: verify ASAP, in the past we had sk_pop_free with q_OPENSSL_sk_free ++ // which seems to be blatantly wrong and even crashes with 1.1. ++ q_OPENSSL_sk_pop_free(reinterpret_cast(ca), ++ reinterpret_cast(q_X509_free)); ++ + q_X509_free(x509); + q_EVP_PKEY_free(pkey); + q_PKCS12_free(p12); +diff --git a/qtbase/src/network/ssl/qsslsocket_openssl11.cpp b/qtbase/src/network/ssl/qsslsocket_openssl11.cpp +new file mode 100644 +index 0000000000..b6d18943a5 +--- /dev/null ++++ b/qtbase/src/network/ssl/qsslsocket_openssl11.cpp +@@ -0,0 +1,285 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2017 The Qt Company Ltd. ++** Copyright (C) 2014 Governikus GmbH & Co. KG ++** Copyright (C) 2016 Richard J. Moore ++** Contact: https://www.qt.io/licensing/ ++** ++** This file is part of the QtNetwork module of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see https://www.qt.io/terms-conditions. For further ++** information use the contact form at https://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 3 as published by the Free Software ++** Foundation and appearing in the file LICENSE.LGPL3 included in the ++** packaging of this file. Please review the following information to ++** ensure the GNU Lesser General Public License version 3 requirements ++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ++** ++** GNU General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU ++** General Public License version 2.0 or (at your option) the GNU General ++** Public license version 3 or any later version approved by the KDE Free ++** Qt Foundation. The licenses are as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ++** included in the packaging of this file. Please review the following ++** information to ensure the GNU General Public License requirements will ++** be met: https://www.gnu.org/licenses/gpl-2.0.html and ++** https://www.gnu.org/licenses/gpl-3.0.html. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++/**************************************************************************** ++** ++** In addition, as a special exception, the copyright holders listed above give ++** permission to link the code of its release of Qt with the OpenSSL project's ++** "OpenSSL" library (or modified versions of the "OpenSSL" library that use the ++** same license as the original version), and distribute the linked executables. ++** ++** You must comply with the GNU General Public License version 2 in all ++** respects for all of the code used other than the "OpenSSL" code. If you ++** modify this file, you may extend this exception to your version of the file, ++** but you are not obligated to do so. If you do not wish to do so, delete ++** this exception statement from your version of this file. ++** ++****************************************************************************/ ++ ++//#define QT_DECRYPT_SSL_TRAFFIC ++ ++#include "qssl_p.h" ++#include "qsslsocket_openssl_p.h" ++#include "qsslsocket_openssl_symbols_p.h" ++#include "qsslsocket.h" ++#include "qsslkey.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++QT_BEGIN_NAMESPACE ++ ++Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_opensslInitMutex, (QMutex::Recursive)) ++ ++/*! ++ \internal ++*/ ++void QSslSocketPrivate::deinitialize() ++{ ++ // This function exists only for compatibility with the pre-11 code, ++ // where deinitialize() actually does some cleanup. To be discarded ++ // once we retire < 1.1. ++} ++ ++bool QSslSocketPrivate::ensureLibraryLoaded() ++{ ++ if (!q_resolveOpenSslSymbols()) ++ return false; ++ ++ const QMutexLocker locker(qt_opensslInitMutex); ++ ++ if (!s_libraryLoaded) { ++ s_libraryLoaded = true; ++ ++ // Initialize OpenSSL. ++ if (q_OPENSSL_init_ssl(0, nullptr) != 1) ++ return false; ++ q_SSL_load_error_strings(); ++ q_OpenSSL_add_all_algorithms(); ++ ++ QSslSocketBackendPrivate::s_indexForSSLExtraData ++ = q_CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, 0L, nullptr, nullptr, ++ nullptr, nullptr); ++ ++ // Initialize OpenSSL's random seed. ++ if (!q_RAND_status()) { ++ qWarning("Random number generator not seeded, disabling SSL support"); ++ return false; ++ } ++ } ++ return true; ++} ++ ++void QSslSocketPrivate::ensureCiphersAndCertsLoaded() ++{ ++ const QMutexLocker locker(qt_opensslInitMutex); ++ ++ if (s_loadedCiphersAndCerts) ++ return; ++ s_loadedCiphersAndCerts = true; ++ ++ resetDefaultCiphers(); ++ resetDefaultEllipticCurves(); ++ ++#if QT_CONFIG(library) ++ //load symbols needed to receive certificates from system store ++#if defined(Q_OS_WIN) ++ HINSTANCE hLib = LoadLibraryW(L"Crypt32"); ++ if (hLib) { ++ ptrCertOpenSystemStoreW = (PtrCertOpenSystemStoreW)GetProcAddress(hLib, "CertOpenSystemStoreW"); ++ ptrCertFindCertificateInStore = (PtrCertFindCertificateInStore)GetProcAddress(hLib, "CertFindCertificateInStore"); ++ ptrCertCloseStore = (PtrCertCloseStore)GetProcAddress(hLib, "CertCloseStore"); ++ if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore) ++ qCWarning(lcSsl, "could not resolve symbols in crypt32 library"); // should never happen ++ } else { ++ qCWarning(lcSsl, "could not load crypt32 library"); // should never happen ++ } ++#elif defined(Q_OS_QNX) ++ s_loadRootCertsOnDemand = true; ++#elif defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) ++ // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there) ++ QList dirs = unixRootCertDirectories(); ++ QStringList symLinkFilter; ++ symLinkFilter << QLatin1String("[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]"); ++ for (int a = 0; a < dirs.count(); ++a) { ++ QDirIterator iterator(QLatin1String(dirs.at(a)), symLinkFilter, QDir::Files); ++ if (iterator.hasNext()) { ++ s_loadRootCertsOnDemand = true; ++ break; ++ } ++ } ++#endif ++#endif // QT_CONFIG(library) ++ // if on-demand loading was not enabled, load the certs now ++ if (!s_loadRootCertsOnDemand) ++ setDefaultCaCertificates(systemCaCertificates()); ++#ifdef Q_OS_WIN ++ //Enabled for fetching additional root certs from windows update on windows 6+ ++ //This flag is set false by setDefaultCaCertificates() indicating the app uses ++ //its own cert bundle rather than the system one. ++ //Same logic that disables the unix on demand cert loading. ++ //Unlike unix, we do preload the certificates from the cert store. ++ if ((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) >= QSysInfo::WV_6_0) ++ s_loadRootCertsOnDemand = true; ++#endif ++} ++ ++long QSslSocketPrivate::sslLibraryVersionNumber() ++{ ++ if (!supportsSsl()) ++ return 0; ++ ++ return q_OpenSSL_version_num(); ++} ++ ++QString QSslSocketPrivate::sslLibraryVersionString() ++{ ++ if (!supportsSsl()) ++ return QString(); ++ ++ const char *versionString = q_OpenSSL_version(OPENSSL_VERSION); ++ if (!versionString) ++ return QString(); ++ ++ return QString::fromLatin1(versionString); ++} ++ ++void QSslSocketBackendPrivate::continueHandshake() ++{ ++ Q_Q(QSslSocket); ++ // if we have a max read buffer size, reset the plain socket's to match ++ if (readBufferMaxSize) ++ plainSocket->setReadBufferSize(readBufferMaxSize); ++ ++ if (q_SSL_session_reused(ssl)) ++ configuration.peerSessionShared = true; ++ ++#ifdef QT_DECRYPT_SSL_TRAFFIC ++ if (q_SSL_get_session(ssl)) { ++ size_t master_key_len = q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl), 0, 0); ++ size_t client_random_len = q_SSL_get_client_random(ssl, 0, 0); ++ QByteArray masterKey(int(master_key_len), 0); // Will not overflow ++ QByteArray clientRandom(int(client_random_len), 0); // Will not overflow ++ ++ q_SSL_SESSION_get_master_key(q_SSL_get_session(ssl), ++ reinterpret_cast(masterKey.data()), ++ masterKey.size()); ++ q_SSL_get_client_random(ssl, reinterpret_cast(clientRandom.data()), ++ clientRandom.size()); ++ ++ QByteArray debugLineClientRandom("CLIENT_RANDOM "); ++ debugLineClientRandom.append(clientRandom.toHex().toUpper()); ++ debugLineClientRandom.append(" "); ++ debugLineClientRandom.append(masterKey.toHex().toUpper()); ++ debugLineClientRandom.append("\n"); ++ ++ QString sslKeyFile = QDir::tempPath() + QLatin1String("/qt-ssl-keys"); ++ QFile file(sslKeyFile); ++ if (!file.open(QIODevice::Append)) ++ qCWarning(lcSsl) << "could not open file" << sslKeyFile << "for appending"; ++ if (!file.write(debugLineClientRandom)) ++ qCWarning(lcSsl) << "could not write to file" << sslKeyFile; ++ file.close(); ++ } else { ++ qCWarning(lcSsl, "could not decrypt SSL traffic"); ++ } ++#endif ++ ++ // Cache this SSL session inside the QSslContext ++ if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionSharing)) { ++ if (!sslContextPointer->cacheSession(ssl)) { ++ sslContextPointer.clear(); // we could not cache the session ++ } else { ++ // Cache the session for permanent usage as well ++ if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionPersistence)) { ++ if (!sslContextPointer->sessionASN1().isEmpty()) ++ configuration.sslSession = sslContextPointer->sessionASN1(); ++ configuration.sslSessionTicketLifeTimeHint = sslContextPointer->sessionTicketLifeTimeHint(); ++ } ++ } ++ } ++ ++#if !defined(OPENSSL_NO_NEXTPROTONEG) ++ ++ configuration.nextProtocolNegotiationStatus = sslContextPointer->npnContext().status; ++ if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) { ++ // we could not agree -> be conservative and use HTTP/1.1 ++ configuration.nextNegotiatedProtocol = QByteArrayLiteral("http/1.1"); ++ } else { ++ const unsigned char *proto = 0; ++ unsigned int proto_len = 0; ++ ++ q_SSL_get0_alpn_selected(ssl, &proto, &proto_len); ++ if (proto_len && mode == QSslSocket::SslClientMode) { ++ // Client does not have a callback that sets it ... ++ configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNegotiated; ++ } ++ ++ if (!proto_len) { // Test if NPN was more lucky ... ++ q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len); ++ } ++ ++ if (proto_len) ++ configuration.nextNegotiatedProtocol = QByteArray(reinterpret_cast(proto), proto_len); ++ else ++ configuration.nextNegotiatedProtocol.clear(); ++ } ++#endif // !defined(OPENSSL_NO_NEXTPROTONEG) ++ ++ if (mode == QSslSocket::SslClientMode) { ++ EVP_PKEY *key; ++ if (q_SSL_get_server_tmp_key(ssl, &key)) ++ configuration.ephemeralServerKey = QSslKey(key, QSsl::PublicKey); ++ } ++ ++ connectionEncrypted = true; ++ emit q->encrypted(); ++ if (autoStartHandshake && pendingClose) { ++ pendingClose = false; ++ q->disconnectFromHost(); ++ } ++} ++ ++QT_END_NAMESPACE +diff --git a/qtbase/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/qtbase/src/network/ssl/qsslsocket_openssl11_symbols_p.h +new file mode 100644 +index 0000000000..2980b3d23e +--- /dev/null ++++ b/qtbase/src/network/ssl/qsslsocket_openssl11_symbols_p.h +@@ -0,0 +1,132 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2017 The Qt Company Ltd. ++** Copyright (C) 2014 BlackBerry Limited. All rights reserved. ++** Copyright (C) 2016 Richard J. Moore ++** Contact: https://www.qt.io/licensing/ ++** ++** This file is part of the QtNetwork module of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see https://www.qt.io/terms-conditions. For further ++** information use the contact form at https://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 3 as published by the Free Software ++** Foundation and appearing in the file LICENSE.LGPL3 included in the ++** packaging of this file. Please review the following information to ++** ensure the GNU Lesser General Public License version 3 requirements ++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ++** ++** GNU General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU ++** General Public License version 2.0 or (at your option) the GNU General ++** Public license version 3 or any later version approved by the KDE Free ++** Qt Foundation. The licenses are as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ++** included in the packaging of this file. Please review the following ++** information to ensure the GNU General Public License requirements will ++** be met: https://www.gnu.org/licenses/gpl-2.0.html and ++** https://www.gnu.org/licenses/gpl-3.0.html. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++/**************************************************************************** ++** ++** In addition, as a special exception, the copyright holders listed above give ++** permission to link the code of its release of Qt with the OpenSSL project's ++** "OpenSSL" library (or modified versions of the "OpenSSL" library that use the ++** same license as the original version), and distribute the linked executables. ++** ++** You must comply with the GNU General Public License version 2 in all ++** respects for all of the code used other than the "OpenSSL" code. If you ++** modify this file, you may extend this exception to your version of the file, ++** but you are not obligated to do so. If you do not wish to do so, delete ++** this exception statement from your version of this file. ++** ++****************************************************************************/ ++ ++#ifndef QSSLSOCKET_OPENSSL11_SYMBOLS_P_H ++#define QSSLSOCKET_OPENSSL11_SYMBOLS_P_H ++ ++// ++// W A R N I N G ++// ------------- ++// ++// This file is not part of the Qt API. It exists purely as an ++// implementation detail. This header file may change from version to ++// version without notice, or even be removed. ++// ++// We mean it. ++// ++ ++// Note: this file does not have QT_BEGIN_NAMESPACE/QT_END_NAMESPACE, it's done ++// in qsslsocket_openssl_symbols_p.h. ++ ++#ifndef QSSLSOCKET_OPENSSL_SYMBOLS_P_H ++#error "You are not supposed to use this header file, include qsslsocket_openssl_symbols_p.h instead" ++#endif ++ ++const unsigned char * q_ASN1_STRING_get0_data(const ASN1_STRING *x); ++ ++Q_AUTOTEST_EXPORT BIO *q_BIO_new(const BIO_METHOD *a); ++Q_AUTOTEST_EXPORT const BIO_METHOD *q_BIO_s_mem(); ++ ++int q_DSA_bits(DSA *a); ++int q_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c); ++int q_EVP_PKEY_base_id(EVP_PKEY *a); ++int q_RSA_bits(RSA *a); ++int q_OPENSSL_sk_num(OPENSSL_STACK *a); ++void q_OPENSSL_sk_pop_free(OPENSSL_STACK *a, void (*b)(void *)); ++OPENSSL_STACK *q_OPENSSL_sk_new_null(); ++void q_OPENSSL_sk_push(OPENSSL_STACK *st, void *data); ++void q_OPENSSL_sk_free(OPENSSL_STACK *a); ++void * q_OPENSSL_sk_value(OPENSSL_STACK *a, int b); ++int q_SSL_session_reused(SSL *a); ++unsigned long q_SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op); ++int q_OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); ++size_t q_SSL_get_client_random(SSL *a, unsigned char *out, size_t outlen); ++size_t q_SSL_SESSION_get_master_key(const SSL_SESSION *session, unsigned char *out, size_t outlen); ++int q_CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); ++const SSL_METHOD *q_TLS_method(); ++const SSL_METHOD *q_TLS_client_method(); ++const SSL_METHOD *q_TLS_server_method(); ++ASN1_TIME *q_X509_getm_notBefore(X509 *a); ++ASN1_TIME *q_X509_getm_notAfter(X509 *a); ++ ++long q_X509_get_version(X509 *a); ++EVP_PKEY *q_X509_get_pubkey(X509 *a); ++void q_X509_STORE_set_verify_cb(X509_STORE *ctx, X509_STORE_CTX_verify_cb verify_cb); ++STACK_OF(X509) *q_X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx); ++void q_DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); ++int q_DH_bits(DH *dh); ++ ++# define q_SSL_load_error_strings() q_OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \ ++ | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL) ++ ++#define q_SKM_sk_num(type, st) ((int (*)(const STACK_OF(type) *))q_OPENSSL_sk_num)(st) ++#define q_SKM_sk_value(type, st,i) ((type * (*)(const STACK_OF(type) *, int))q_OPENSSL_sk_value)(st, i) ++ ++#define q_OPENSSL_add_all_algorithms_conf() q_OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \ ++ | OPENSSL_INIT_ADD_ALL_DIGESTS \ ++ | OPENSSL_INIT_LOAD_CONFIG, NULL) ++#define q_OPENSSL_add_all_algorithms_noconf() q_OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \ ++ | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL) ++ ++int q_OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); ++void q_CRYPTO_free(void *str, const char *file, int line); ++ ++long q_OpenSSL_version_num(); ++const char *q_OpenSSL_version(int type); ++ ++unsigned long q_SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session); ++ ++#endif +diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_p.h +index b2adb3e547..7f9e884045 100644 +--- a/qtbase/src/network/ssl/qsslsocket_openssl_p.h ++++ b/qtbase/src/network/ssl/qsslsocket_openssl_p.h +@@ -1,6 +1,6 @@ + /**************************************************************************** + ** +-** Copyright (C) 2016 The Qt Company Ltd. ++** Copyright (C) 2017 The Qt Company Ltd. + ** Contact: https://www.qt.io/licensing/ + ** + ** This file is part of the QtNetwork module of the Qt Toolkit. +@@ -98,8 +98,8 @@ + #include + #include + +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L +-typedef _STACK STACK; ++#if QT_CONFIG(opensslv11) ++#include + #endif + + QT_BEGIN_NAMESPACE +@@ -151,7 +151,7 @@ public: + #endif + + Q_AUTOTEST_EXPORT static long setupOpenSslOptions(QSsl::SslProtocol protocol, QSsl::SslOptions sslOptions); +- static QSslCipher QSslCipher_from_SSL_CIPHER(SSL_CIPHER *cipher); ++ static QSslCipher QSslCipher_from_SSL_CIPHER(const SSL_CIPHER *cipher); + static QList STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509); + static QList verify(const QList &certificateChain, const QString &hostName); + static QString getErrorsFromOpenSsl(); +diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp +index c344a94427..0ef8bf6b5e 100644 +--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp ++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols.cpp +@@ -1,7 +1,8 @@ + /**************************************************************************** + ** +-** Copyright (C) 2016 The Qt Company Ltd. ++** Copyright (C) 2017 The Qt Company Ltd. + ** Copyright (C) 2014 BlackBerry Limited. All rights reserved. ++** Copyright (C) 2016 Richard J. Moore + ** Contact: https://www.qt.io/licensing/ + ** + ** This file is part of the QtNetwork module of the Qt Toolkit. +@@ -136,49 +137,195 @@ void qsslSocketCannotResolveSymbolWarning(const char *functionName) + + #endif // QT_LINKED_OPENSSL + ++#if QT_CONFIG(opensslv11) ++ ++// Below are the functions first introduced in version 1.1: ++ ++DEFINEFUNC(const unsigned char *, ASN1_STRING_get0_data, const ASN1_STRING *a, a, return 0, return) ++DEFINEFUNC2(int, OPENSSL_init_ssl, uint64_t opts, opts, const OPENSSL_INIT_SETTINGS *settings, settings, return 0, return) ++DEFINEFUNC2(int, OPENSSL_init_crypto, uint64_t opts, opts, const OPENSSL_INIT_SETTINGS *settings, settings, return 0, return) ++DEFINEFUNC(BIO *, BIO_new, const BIO_METHOD *a, a, return 0, return) ++DEFINEFUNC(const BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return) ++DEFINEFUNC2(int, BN_is_word, BIGNUM *a, a, BN_ULONG w, w, return 0, return) ++DEFINEFUNC(int, EVP_CIPHER_CTX_reset, EVP_CIPHER_CTX *c, c, return 0, return) ++DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return) ++DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return) ++DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return) ++DEFINEFUNC(int, OPENSSL_sk_num, OPENSSL_STACK *a, a, return -1, return) ++DEFINEFUNC2(void, OPENSSL_sk_pop_free, OPENSSL_STACK *a, a, void (*b)(void*), b, return, DUMMYARG) ++DEFINEFUNC(OPENSSL_STACK *, OPENSSL_sk_new_null, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC2(void, OPENSSL_sk_push, OPENSSL_STACK *a, a, void *b, b, return, DUMMYARG) ++DEFINEFUNC(void, OPENSSL_sk_free, OPENSSL_STACK *a, a, return, DUMMYARG) ++DEFINEFUNC2(void *, OPENSSL_sk_value, OPENSSL_STACK *a, a, int b, b, return 0, return) ++DEFINEFUNC(int, SSL_session_reused, SSL *a, a, return 0, return) ++DEFINEFUNC2(unsigned long, SSL_CTX_set_options, SSL_CTX *ctx, ctx, unsigned long op, op, return 0, return) ++DEFINEFUNC3(size_t, SSL_get_client_random, SSL *a, a, unsigned char *out, out, size_t outlen, outlen, return 0, return) ++DEFINEFUNC3(size_t, SSL_SESSION_get_master_key, const SSL_SESSION *ses, ses, unsigned char *out, out, size_t outlen, outlen, return 0, return) ++DEFINEFUNC6(int, CRYPTO_get_ex_new_index, int class_index, class_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return) ++ ++DEFINEFUNC(const SSL_METHOD *, TLS_method, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC(const SSL_METHOD *, TLS_client_method, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC(const SSL_METHOD *, TLS_server_method, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC(ASN1_TIME *, X509_getm_notBefore, X509 *a, a, return 0, return) ++DEFINEFUNC(ASN1_TIME *, X509_getm_notAfter, X509 *a, a, return 0, return) ++DEFINEFUNC(long, X509_get_version, X509 *a, a, return -1, return) ++DEFINEFUNC(EVP_PKEY *, X509_get_pubkey, X509 *a, a, return 0, return) ++DEFINEFUNC2(void, X509_STORE_set_verify_cb, X509_STORE *a, a, X509_STORE_CTX_verify_cb verify_cb, verify_cb, return, DUMMYARG) ++DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get0_chain, X509_STORE_CTX *a, a, return 0, return) ++DEFINEFUNC3(void, CRYPTO_free, void *str, str, const char *file, file, int line, line, return, DUMMYARG) ++DEFINEFUNC(long, OpenSSL_version_num, void, DUMMYARG, return 0, return) ++DEFINEFUNC(const char *, OpenSSL_version, int a, a, return 0, return) ++DEFINEFUNC(unsigned long, SSL_SESSION_get_ticket_lifetime_hint, const SSL_SESSION *session, session, return 0, return) ++DEFINEFUNC4(void, DH_get0_pqg, const DH *dh, dh, const BIGNUM **p, p, const BIGNUM **q, q, const BIGNUM **g, g, return, DUMMYARG) ++DEFINEFUNC(int, DH_bits, DH *dh, dh, return 0, return) ++ ++#else // QT_CONFIG(opensslv11) ++ ++// Functions below are either deprecated or removed in OpenSSL >= 1.1: ++ ++DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return 0, return) ++ + #ifdef SSLEAY_MACROS + DEFINEFUNC3(void *, ASN1_dup, i2d_of_void *a, a, d2i_of_void *b, b, char *c, c, return 0, return) + #endif ++DEFINEFUNC2(BIO *, BIO_new_file, const char *filename, filename, const char *mode, mode, return 0, return) ++DEFINEFUNC(void, ERR_clear_error, DUMMYARG, DUMMYARG, return, DUMMYARG) ++DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return 0, return) ++DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return) ++DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG) ++DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG) ++DEFINEFUNC(void, CRYPTO_free, void *a, a, return, DUMMYARG) ++DEFINEFUNC(unsigned long, ERR_peek_last_error, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC(void, ERR_free_strings, void, DUMMYARG, return, DUMMYARG) ++DEFINEFUNC(void, EVP_CIPHER_CTX_cleanup, EVP_CIPHER_CTX *a, a, return, DUMMYARG) ++DEFINEFUNC(void, EVP_CIPHER_CTX_init, EVP_CIPHER_CTX *a, a, return, DUMMYARG) ++ ++#ifdef SSLEAY_MACROS ++DEFINEFUNC6(void *, PEM_ASN1_read_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return) ++DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return) ++#endif // SSLEAY_MACROS ++ ++DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return) ++DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG) ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10000000L ++DEFINEFUNC(_STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC2(void, sk_push, _STACK *a, a, void *b, b, return, DUMMYARG) ++DEFINEFUNC(void, sk_free, _STACK *a, a, return, DUMMYARG) ++DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return 0, return) ++#else ++DEFINEFUNC(STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC2(void, sk_push, STACK *a, a, char *b, b, return, DUMMYARG) ++DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG) ++DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return 0, return) ++#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L ++ ++DEFINEFUNC(int, SSL_library_init, void, DUMMYARG, return -1, return) ++DEFINEFUNC(void, SSL_load_error_strings, void, DUMMYARG, return, DUMMYARG) ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10001000L ++DEFINEFUNC5(int, SSL_get_ex_new_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return) ++#endif // OPENSSL_VERSION_NUMBER >= 0x10001000L ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10000000L ++#ifndef OPENSSL_NO_SSL2 ++DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return) ++#endif ++#ifndef OPENSSL_NO_SSL3_METHOD ++DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return) ++#endif ++DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return) ++#if OPENSSL_VERSION_NUMBER >= 0x10001000L ++DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return 0, return) ++#endif ++#ifndef OPENSSL_NO_SSL2 ++DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return) ++#endif ++#ifndef OPENSSL_NO_SSL3_METHOD ++DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return) ++#endif ++DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return) ++#if OPENSSL_VERSION_NUMBER >= 0x10001000L ++DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return 0, return) ++#endif ++#else ++#ifndef OPENSSL_NO_SSL2 ++DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return) ++#endif ++#ifndef OPENSSL_NO_SSL3_METHOD ++DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return) ++#endif ++DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return) ++#ifndef OPENSSL_NO_SSL2 ++DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return) ++#endif ++#ifndef OPENSSL_NO_SSL3_METHOD ++DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return) ++#endif ++DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return) ++#endif ++ ++DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get_chain, X509_STORE_CTX *a, a, return 0, return) ++ ++#ifdef SSLEAY_MACROS ++DEFINEFUNC2(int, i2d_DSAPrivateKey, const DSA *a, a, unsigned char **b, b, return -1, return) ++DEFINEFUNC2(int, i2d_RSAPrivateKey, const RSA *a, a, unsigned char **b, b, return -1, return) ++#ifndef OPENSSL_NO_EC ++DEFINEFUNC2(int, i2d_ECPrivateKey, const EC_KEY *a, a, unsigned char **b, b, return -1, return) ++#endif ++DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return 0, return) ++DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return 0, return) ++#ifndef OPENSSL_NO_EC ++DEFINEFUNC3(EC_KEY *, d2i_ECPrivateKey, EC_KEY **a, a, unsigned char **b, b, long c, c, return 0, return) ++#endif ++#endif ++DEFINEFUNC(char *, CONF_get1_default_config_file, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG) ++DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG) ++DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return) ++DEFINEFUNC(const char *, SSLeay_version, int a, a, return 0, return) ++ ++#endif // QT_CONFIG(opensslv11) ++ + DEFINEFUNC(long, ASN1_INTEGER_get, ASN1_INTEGER *a, a, return 0, return) +-DEFINEFUNC(unsigned char *, ASN1_STRING_data, ASN1_STRING *a, a, return 0, return) + DEFINEFUNC(int, ASN1_STRING_length, ASN1_STRING *a, a, return 0, return) +-DEFINEFUNC2(int, ASN1_STRING_to_UTF8, unsigned char **a, a, ASN1_STRING *b, b, return 0, return); ++DEFINEFUNC2(int, ASN1_STRING_to_UTF8, unsigned char **a, a, ASN1_STRING *b, b, return 0, return) + DEFINEFUNC4(long, BIO_ctrl, BIO *a, a, int b, b, long c, c, void *d, d, return -1, return) + DEFINEFUNC(int, BIO_free, BIO *a, a, return 0, return) +-DEFINEFUNC(BIO *, BIO_new, BIO_METHOD *a, a, return 0, return) + DEFINEFUNC2(BIO *, BIO_new_mem_buf, void *a, a, int b, b, return 0, return) + DEFINEFUNC3(int, BIO_read, BIO *a, a, void *b, b, int c, c, return -1, return) +-DEFINEFUNC(BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return 0, return) ++ + DEFINEFUNC3(int, BIO_write, BIO *a, a, const void *b, b, int c, c, return -1, return) + DEFINEFUNC(int, BN_num_bits, const BIGNUM *a, a, return 0, return) +-#if OPENSSL_VERSION_NUMBER >= 0x10100000L +-DEFINEFUNC2(int, BN_is_word, BIGNUM *a, a, BN_ULONG w, w, return 0, return) +-#endif + DEFINEFUNC2(BN_ULONG, BN_mod_word, const BIGNUM *a, a, BN_ULONG w, w, return static_cast(-1), return) + #ifndef OPENSSL_NO_EC + DEFINEFUNC(const EC_GROUP*, EC_KEY_get0_group, const EC_KEY* k, k, return 0, return) + DEFINEFUNC(int, EC_GROUP_get_degree, const EC_GROUP* g, g, return 0, return) + #endif +-DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return) +-DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG) +-DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG) +-DEFINEFUNC(void, CRYPTO_free, void *a, a, return, DUMMYARG) + DEFINEFUNC(DSA *, DSA_new, DUMMYARG, DUMMYARG, return 0, return) + DEFINEFUNC(void, DSA_free, DSA *a, a, return, DUMMYARG) + DEFINEFUNC3(X509 *, d2i_X509, X509 **a, a, const unsigned char **b, b, long c, c, return 0, return) + DEFINEFUNC2(char *, ERR_error_string, unsigned long a, a, char *b, b, return 0, return) + DEFINEFUNC(unsigned long, ERR_get_error, DUMMYARG, DUMMYARG, return 0, return) +-DEFINEFUNC(void, ERR_free_strings, void, DUMMYARG, return, DUMMYARG) +-DEFINEFUNC(void, EVP_CIPHER_CTX_cleanup, EVP_CIPHER_CTX *a, a, return, DUMMYARG) +-DEFINEFUNC(void, EVP_CIPHER_CTX_init, EVP_CIPHER_CTX *a, a, return, DUMMYARG) +-DEFINEFUNC4(int, EVP_CIPHER_CTX_ctrl, EVP_CIPHER_CTX *ctx, ctx, int type, type, int arg, arg, void *ptr, ptr, return 0, return); ++DEFINEFUNC(EVP_CIPHER_CTX *, EVP_CIPHER_CTX_new, void, DUMMYARG, return 0, return) ++DEFINEFUNC(void, EVP_CIPHER_CTX_free, EVP_CIPHER_CTX *a, a, return, DUMMYARG) ++DEFINEFUNC4(int, EVP_CIPHER_CTX_ctrl, EVP_CIPHER_CTX *ctx, ctx, int type, type, int arg, arg, void *ptr, ptr, return 0, return) + DEFINEFUNC2(int, EVP_CIPHER_CTX_set_key_length, EVP_CIPHER_CTX *ctx, ctx, int keylen, keylen, return 0, return) +-DEFINEFUNC5(int, EVP_CipherInit, EVP_CIPHER_CTX *ctx, ctx, const EVP_CIPHER *type, type, const unsigned char *key, key, const unsigned char *iv, iv, int enc, enc, return 0, return); +-DEFINEFUNC5(int, EVP_CipherUpdate, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, const unsigned char *in, in, int inl, inl, return 0, return); +-DEFINEFUNC3(int, EVP_CipherFinal, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, return 0, return); ++DEFINEFUNC5(int, EVP_CipherInit, EVP_CIPHER_CTX *ctx, ctx, const EVP_CIPHER *type, type, const unsigned char *key, key, const unsigned char *iv, iv, int enc, enc, return 0, return) ++DEFINEFUNC6(int, EVP_CipherInit_ex, EVP_CIPHER_CTX *ctx, ctx, const EVP_CIPHER *cipher, cipher, ENGINE *impl, impl, const unsigned char *key, key, const unsigned char *iv, iv, int enc, enc, return 0, return) ++DEFINEFUNC5(int, EVP_CipherUpdate, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, const unsigned char *in, in, int inl, inl, return 0, return) ++DEFINEFUNC3(int, EVP_CipherFinal, EVP_CIPHER_CTX *ctx, ctx, unsigned char *out, out, int *outl, outl, return 0, return) + DEFINEFUNC(const EVP_CIPHER *, EVP_des_cbc, DUMMYARG, DUMMYARG, return 0, return) + DEFINEFUNC(const EVP_CIPHER *, EVP_des_ede3_cbc, DUMMYARG, DUMMYARG, return 0, return) + DEFINEFUNC(const EVP_CIPHER *, EVP_rc2_cbc, DUMMYARG, DUMMYARG, return 0, return) ++DEFINEFUNC(const EVP_MD *, EVP_sha1, DUMMYARG, DUMMYARG, return 0, return) + DEFINEFUNC3(int, EVP_PKEY_assign, EVP_PKEY *a, a, int b, b, char *c, c, return -1, return) + DEFINEFUNC2(int, EVP_PKEY_set1_RSA, EVP_PKEY *a, a, RSA *b, b, return -1, return) + DEFINEFUNC2(int, EVP_PKEY_set1_DSA, EVP_PKEY *a, a, DSA *b, b, return -1, return) +@@ -202,10 +349,8 @@ DEFINEFUNC3(int, i2t_ASN1_OBJECT, char *a, a, int b, b, ASN1_OBJECT *c, c, retur + DEFINEFUNC4(int, OBJ_obj2txt, char *a, a, int b, b, ASN1_OBJECT *c, c, int d, d, return -1, return) + + DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return) +-#ifdef SSLEAY_MACROS +-DEFINEFUNC6(void *, PEM_ASN1_read_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return) +-DEFINEFUNC6(void *, PEM_ASN1_write_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return) +-#else ++ ++#ifndef SSLEAY_MACROS + DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PrivateKey, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return) + DEFINEFUNC4(DSA *, PEM_read_bio_DSAPrivateKey, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return) + DEFINEFUNC4(RSA *, PEM_read_bio_RSAPrivateKey, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return) +@@ -218,7 +363,7 @@ DEFINEFUNC7(int, PEM_write_bio_RSAPrivateKey, BIO *a, a, RSA *b, b, const EVP_CI + #ifndef OPENSSL_NO_EC + DEFINEFUNC7(int, PEM_write_bio_ECPrivateKey, BIO *a, a, EC_KEY *b, b, const EVP_CIPHER *c, c, unsigned char *d, d, int e, e, pem_password_cb *f, f, void *g, g, return 0, return) + #endif +-#endif ++#endif // !SSLEAY_MACROS + DEFINEFUNC4(EVP_PKEY *, PEM_read_bio_PUBKEY, BIO *a, a, EVP_PKEY **b, b, pem_password_cb *c, c, void *d, d, return 0, return) + DEFINEFUNC4(DSA *, PEM_read_bio_DSA_PUBKEY, BIO *a, a, DSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return) + DEFINEFUNC4(RSA *, PEM_read_bio_RSA_PUBKEY, BIO *a, a, RSA **b, b, pem_password_cb *c, c, void *d, d, return 0, return) +@@ -234,23 +379,10 @@ DEFINEFUNC2(void, RAND_seed, const void *a, a, int b, b, return, DUMMYARG) + DEFINEFUNC(int, RAND_status, void, DUMMYARG, return -1, return) + DEFINEFUNC(RSA *, RSA_new, DUMMYARG, DUMMYARG, return 0, return) + DEFINEFUNC(void, RSA_free, RSA *a, a, return, DUMMYARG) +-DEFINEFUNC(int, sk_num, STACK *a, a, return -1, return) +-DEFINEFUNC2(void, sk_pop_free, STACK *a, a, void (*b)(void*), b, return, DUMMYARG) +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L +-DEFINEFUNC(_STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return) +-DEFINEFUNC2(void, sk_push, _STACK *a, a, void *b, b, return, DUMMYARG) +-DEFINEFUNC(void, sk_free, _STACK *a, a, return, DUMMYARG) +-DEFINEFUNC2(void *, sk_value, STACK *a, a, int b, b, return 0, return) +-#else +-DEFINEFUNC(STACK *, sk_new_null, DUMMYARG, DUMMYARG, return 0, return) +-DEFINEFUNC2(void, sk_push, STACK *a, a, char *b, b, return, DUMMYARG) +-DEFINEFUNC(void, sk_free, STACK *a, a, return, DUMMYARG) +-DEFINEFUNC2(char *, sk_value, STACK *a, a, int b, b, return 0, return) +-#endif + DEFINEFUNC(int, SSL_accept, SSL *a, a, return -1, return) + DEFINEFUNC(int, SSL_clear, SSL *a, a, return -1, return) +-DEFINEFUNC3(char *, SSL_CIPHER_description, SSL_CIPHER *a, a, char *b, b, int c, c, return 0, return) +-DEFINEFUNC2(int, SSL_CIPHER_get_bits, SSL_CIPHER *a, a, int *b, b, return 0, return) ++DEFINEFUNC3(char *, SSL_CIPHER_description, const SSL_CIPHER *a, a, char *b, b, int c, c, return 0, return) ++DEFINEFUNC2(int, SSL_CIPHER_get_bits, const SSL_CIPHER *a, a, int *b, b, return 0, return) + DEFINEFUNC(int, SSL_connect, SSL *a, a, return -1, return) + DEFINEFUNC(int, SSL_CTX_check_private_key, const SSL_CTX *a, a, return -1, return) + DEFINEFUNC4(long, SSL_CTX_ctrl, SSL_CTX *a, a, int b, b, long c, c, void *d, d, return -1, return) +@@ -287,8 +419,6 @@ DEFINEFUNC(long, SSL_get_verify_result, const SSL *a, a, return -1, return) + #else + DEFINEFUNC(long, SSL_get_verify_result, SSL *a, a, return -1, return) + #endif +-DEFINEFUNC(int, SSL_library_init, void, DUMMYARG, return -1, return) +-DEFINEFUNC(void, SSL_load_error_strings, void, DUMMYARG, return, DUMMYARG) + DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return 0, return) + DEFINEFUNC4(long, SSL_ctrl, SSL *a, a, int cmd, cmd, long larg, larg, void *parg, parg, return -1, return) + DEFINEFUNC3(int, SSL_read, SSL *a, a, void *b, b, int c, c, return -1, return) +@@ -301,7 +431,6 @@ DEFINEFUNC(void, SSL_SESSION_free, SSL_SESSION *ses, ses, return, DUMMYARG) + DEFINEFUNC(SSL_SESSION*, SSL_get1_session, SSL *ssl, ssl, return 0, return) + DEFINEFUNC(SSL_SESSION*, SSL_get_session, const SSL *ssl, ssl, return 0, return) + #if OPENSSL_VERSION_NUMBER >= 0x10001000L +-DEFINEFUNC5(int, SSL_get_ex_new_index, long argl, argl, void *argp, argp, CRYPTO_EX_new *new_func, new_func, CRYPTO_EX_dup *dup_func, dup_func, CRYPTO_EX_free *free_func, free_func, return -1, return) + DEFINEFUNC3(int, SSL_set_ex_data, SSL *ssl, ssl, int idx, idx, void *arg, arg, return 0, return) + DEFINEFUNC2(void *, SSL_get_ex_data, const SSL *ssl, ssl, int idx, idx, return NULL, return) + #endif +@@ -310,51 +439,9 @@ DEFINEFUNC2(void, SSL_set_psk_client_callback, SSL* ssl, ssl, q_psk_client_callb + DEFINEFUNC2(void, SSL_set_psk_server_callback, SSL* ssl, ssl, q_psk_server_callback_t callback, callback, return, DUMMYARG) + DEFINEFUNC2(int, SSL_CTX_use_psk_identity_hint, SSL_CTX* ctx, ctx, const char *hint, hint, return 0, return) + #endif +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L +-#ifndef OPENSSL_NO_SSL2 +-DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return) +-#endif +-#ifndef OPENSSL_NO_SSL3_METHOD +-DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return) +-#endif +-DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return) +-DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return) +-#if OPENSSL_VERSION_NUMBER >= 0x10001000L +-DEFINEFUNC(const SSL_METHOD *, TLSv1_1_client_method, DUMMYARG, DUMMYARG, return 0, return) +-DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return 0, return) +-#endif +-#ifndef OPENSSL_NO_SSL2 +-DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return) +-#endif +-#ifndef OPENSSL_NO_SSL3_METHOD +-DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return) +-#endif +-DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return) +-DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return) +-#if OPENSSL_VERSION_NUMBER >= 0x10001000L +-DEFINEFUNC(const SSL_METHOD *, TLSv1_1_server_method, DUMMYARG, DUMMYARG, return 0, return) +-DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return 0, return) +-#endif +-#else +-#ifndef OPENSSL_NO_SSL2 +-DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return) +-#endif +-#ifndef OPENSSL_NO_SSL3_METHOD +-DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return) +-#endif +-DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return) +-DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return) +-#ifndef OPENSSL_NO_SSL2 +-DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return) +-#endif +-#ifndef OPENSSL_NO_SSL3_METHOD +-DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return) +-#endif +-DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return) +-DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return) +-#endif + DEFINEFUNC3(int, SSL_write, SSL *a, a, const void *b, b, int c, c, return -1, return) + DEFINEFUNC2(int, X509_cmp, X509 *a, a, X509 *b, b, return -1, return) ++DEFINEFUNC4(int, X509_digest, const X509 *x509, x509, const EVP_MD *type, type, unsigned char *md, md, unsigned int *len, len, return -1, return) + #ifndef SSLEAY_MACROS + DEFINEFUNC(X509 *, X509_dup, X509 *a, a, return 0, return) + #endif +@@ -378,6 +465,7 @@ DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, ASN1_STRING *b, b, return 0, retu + DEFINEFUNC2(int, X509_check_issued, X509 *a, a, X509 *b, b, return -1, return) + DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return 0, return) + DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return 0, return) ++DEFINEFUNC(ASN1_INTEGER *, X509_get_serialNumber, X509 *a, a, return 0, return) + DEFINEFUNC(int, X509_verify_cert, X509_STORE_CTX *a, a, return -1, return) + DEFINEFUNC(int, X509_NAME_entry_count, X509_NAME *a, a, return 0, return) + DEFINEFUNC2(X509_NAME_ENTRY *, X509_NAME_get_entry, X509_NAME *a, a, int b, b, return 0, return) +@@ -393,25 +481,8 @@ DEFINEFUNC2(int, X509_STORE_CTX_set_purpose, X509_STORE_CTX *a, a, int b, b, ret + DEFINEFUNC(int, X509_STORE_CTX_get_error, X509_STORE_CTX *a, a, return -1, return) + DEFINEFUNC(int, X509_STORE_CTX_get_error_depth, X509_STORE_CTX *a, a, return -1, return) + DEFINEFUNC(X509 *, X509_STORE_CTX_get_current_cert, X509_STORE_CTX *a, a, return 0, return) +-DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get_chain, X509_STORE_CTX *a, a, return 0, return) + DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return 0, return) +-#ifdef SSLEAY_MACROS +-DEFINEFUNC2(int, i2d_DSAPrivateKey, const DSA *a, a, unsigned char **b, b, return -1, return) +-DEFINEFUNC2(int, i2d_RSAPrivateKey, const RSA *a, a, unsigned char **b, b, return -1, return) +-#ifndef OPENSSL_NO_EC +-DEFINEFUNC2(int, i2d_ECPrivateKey, const EC_KEY *a, a, unsigned char **b, b, return -1, return) +-#endif +-DEFINEFUNC3(RSA *, d2i_RSAPrivateKey, RSA **a, a, unsigned char **b, b, long c, c, return 0, return) +-DEFINEFUNC3(DSA *, d2i_DSAPrivateKey, DSA **a, a, unsigned char **b, b, long c, c, return 0, return) +-#ifndef OPENSSL_NO_EC +-DEFINEFUNC3(EC_KEY *, d2i_ECPrivateKey, EC_KEY **a, a, unsigned char **b, b, long c, c, return 0, return) +-#endif +-#endif +-DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMMYARG) +-DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG) + DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return) +-DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return) +-DEFINEFUNC(const char *, SSLeay_version, int a, a, return 0, return) + DEFINEFUNC2(int, i2d_SSL_SESSION, SSL_SESSION *in, in, unsigned char **pp, pp, return 0, return) + DEFINEFUNC3(SSL_SESSION *, d2i_SSL_SESSION, SSL_SESSION **a, a, const unsigned char **pp, pp, long length, length, return 0, return) + #if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG) +@@ -694,8 +765,8 @@ static QPair loadOpenSsl() + #ifndef Q_OS_DARWIN + // second attempt: find the development files libssl.so and libcrypto.so + // +- // disabled on OS X/iOS: +- // OS X's /usr/lib/libssl.dylib, /usr/lib/libcrypto.dylib will be picked up in the third ++ // disabled on macOS/iOS: ++ // macOS's /usr/lib/libssl.dylib, /usr/lib/libcrypto.dylib will be picked up in the third + // attempt, _after_ /Contents/Frameworks has been searched. + // iOS does not ship a system libssl.dylib, libcrypto.dylib in the first place. + libssl->setFileNameAndVersion(QLatin1String("ssl"), -1); +@@ -754,7 +825,11 @@ bool q_resolveOpenSslSymbols() + static bool symbolsResolved = false; + static bool triedToResolveSymbols = false; + #ifndef QT_NO_THREAD ++#if QT_CONFIG(opensslv11) ++ QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_OPENSSL_init_ssl)); ++#else + QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_SSL_library_init)); ++#endif + #endif + if (symbolsResolved) + return true; +@@ -771,11 +846,145 @@ bool q_resolveOpenSslSymbols() + // failed to load them + return false; + ++#if QT_CONFIG(opensslv11) ++ ++ RESOLVEFUNC(OPENSSL_init_ssl) ++ RESOLVEFUNC(OPENSSL_init_crypto) ++ RESOLVEFUNC(ASN1_STRING_get0_data) ++ RESOLVEFUNC(EVP_CIPHER_CTX_reset) ++ RESOLVEFUNC(EVP_PKEY_base_id) ++ RESOLVEFUNC(RSA_bits) ++ RESOLVEFUNC(OPENSSL_sk_new_null) ++ RESOLVEFUNC(OPENSSL_sk_push) ++ RESOLVEFUNC(OPENSSL_sk_free) ++ RESOLVEFUNC(OPENSSL_sk_num) ++ RESOLVEFUNC(OPENSSL_sk_pop_free) ++ RESOLVEFUNC(OPENSSL_sk_value) ++ RESOLVEFUNC(DH_get0_pqg) ++ RESOLVEFUNC(SSL_CTX_set_options) ++ RESOLVEFUNC(SSL_get_client_random) ++ RESOLVEFUNC(SSL_SESSION_get_master_key) ++ RESOLVEFUNC(SSL_session_reused) ++ RESOLVEFUNC(SSL_get_session) ++ RESOLVEFUNC(CRYPTO_get_ex_new_index) ++ RESOLVEFUNC(TLS_method) ++ RESOLVEFUNC(TLS_client_method) ++ RESOLVEFUNC(TLS_server_method) ++ RESOLVEFUNC(X509_STORE_CTX_get0_chain) ++ RESOLVEFUNC(X509_getm_notBefore) ++ RESOLVEFUNC(X509_getm_notAfter) ++ RESOLVEFUNC(X509_get_version) ++ RESOLVEFUNC(X509_get_pubkey) ++ RESOLVEFUNC(X509_STORE_set_verify_cb) ++ RESOLVEFUNC(CRYPTO_free) ++ RESOLVEFUNC(OpenSSL_version_num) ++ RESOLVEFUNC(OpenSSL_version) ++ if (!_q_OpenSSL_version) { ++ // Apparently, we were built with OpenSSL 1.1 enabled but are now using ++ // a wrong library. ++ delete libs.first; ++ delete libs.second; ++ qCWarning(lcSsl, "Incompatible version of OpenSSL"); ++ return false; ++ } ++ ++ RESOLVEFUNC(SSL_SESSION_get_ticket_lifetime_hint) ++ RESOLVEFUNC(DH_bits) ++ RESOLVEFUNC(DSA_bits) ++ ++#else // !opensslv11 ++ ++ RESOLVEFUNC(ASN1_STRING_data) ++ + #ifdef SSLEAY_MACROS + RESOLVEFUNC(ASN1_dup) ++#endif // SSLEAY_MACROS ++ RESOLVEFUNC(BIO_new_file) ++ RESOLVEFUNC(ERR_clear_error) ++ RESOLVEFUNC(CRYPTO_free) ++ RESOLVEFUNC(CRYPTO_num_locks) ++ RESOLVEFUNC(CRYPTO_set_id_callback) ++ RESOLVEFUNC(CRYPTO_set_locking_callback) ++ RESOLVEFUNC(ERR_peek_last_error) ++ RESOLVEFUNC(ERR_free_strings) ++ RESOLVEFUNC(EVP_CIPHER_CTX_cleanup) ++ RESOLVEFUNC(EVP_CIPHER_CTX_init) ++ ++#ifdef SSLEAY_MACROS // ### verify ++ RESOLVEFUNC(PEM_ASN1_read_bio) ++#endif // SSLEAY_MACROS ++ ++ RESOLVEFUNC(sk_new_null) ++ RESOLVEFUNC(sk_push) ++ RESOLVEFUNC(sk_free) ++ RESOLVEFUNC(sk_num) ++ RESOLVEFUNC(sk_pop_free) ++ RESOLVEFUNC(sk_value) ++ RESOLVEFUNC(SSL_library_init) ++ RESOLVEFUNC(SSL_load_error_strings) ++#if OPENSSL_VERSION_NUMBER >= 0x10001000L ++ RESOLVEFUNC(SSL_get_ex_new_index) ++#endif ++#ifndef OPENSSL_NO_SSL2 ++ RESOLVEFUNC(SSLv2_client_method) + #endif ++#ifndef OPENSSL_NO_SSL3_METHOD ++ RESOLVEFUNC(SSLv3_client_method) ++#endif ++ RESOLVEFUNC(SSLv23_client_method) ++ RESOLVEFUNC(TLSv1_client_method) ++#if OPENSSL_VERSION_NUMBER >= 0x10001000L ++ RESOLVEFUNC(TLSv1_1_client_method) ++ RESOLVEFUNC(TLSv1_2_client_method) ++#endif ++#ifndef OPENSSL_NO_SSL2 ++ RESOLVEFUNC(SSLv2_server_method) ++#endif ++#ifndef OPENSSL_NO_SSL3_METHOD ++ RESOLVEFUNC(SSLv3_server_method) ++#endif ++ RESOLVEFUNC(SSLv23_server_method) ++ RESOLVEFUNC(TLSv1_server_method) ++#if OPENSSL_VERSION_NUMBER >= 0x10001000L ++ RESOLVEFUNC(TLSv1_1_server_method) ++ RESOLVEFUNC(TLSv1_2_server_method) ++#endif ++ RESOLVEFUNC(X509_STORE_CTX_get_chain) ++#ifdef SSLEAY_MACROS ++ RESOLVEFUNC(i2d_DSAPrivateKey) ++ RESOLVEFUNC(i2d_RSAPrivateKey) ++ RESOLVEFUNC(d2i_DSAPrivateKey) ++ RESOLVEFUNC(d2i_RSAPrivateKey) ++#endif ++ RESOLVEFUNC(CONF_get1_default_config_file) ++ RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf) ++ RESOLVEFUNC(OPENSSL_add_all_algorithms_conf) ++ RESOLVEFUNC(SSLeay) ++ ++ if (!_q_SSLeay || q_SSLeay() >= 0x10100000L) { ++ // OpenSSL 1.1 has deprecated and removed SSLeay. We consider a failure to ++ // resolve this symbol as a failure to resolve symbols. ++ // The right operand of '||' above is ... a bit of paranoia. ++ delete libs.first; ++ delete libs.second; ++ qCWarning(lcSsl, "Incompatible version of OpenSSL"); ++ return false; ++ } ++ ++ ++ RESOLVEFUNC(SSLeay_version) ++ ++#ifndef OPENSSL_NO_EC ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L ++ if (q_SSLeay() >= 0x10002000L) ++ RESOLVEFUNC(EC_curve_nist2nid) ++#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ++#endif // OPENSSL_NO_EC ++ ++ ++#endif // !opensslv11 ++ + RESOLVEFUNC(ASN1_INTEGER_get) +- RESOLVEFUNC(ASN1_STRING_data) + RESOLVEFUNC(ASN1_STRING_length) + RESOLVEFUNC(ASN1_STRING_to_UTF8) + RESOLVEFUNC(BIO_ctrl) +@@ -794,25 +1003,22 @@ bool q_resolveOpenSslSymbols() + RESOLVEFUNC(BN_is_word) + #endif + RESOLVEFUNC(BN_mod_word) +- RESOLVEFUNC(CRYPTO_free) +- RESOLVEFUNC(CRYPTO_num_locks) +- RESOLVEFUNC(CRYPTO_set_id_callback) +- RESOLVEFUNC(CRYPTO_set_locking_callback) + RESOLVEFUNC(DSA_new) + RESOLVEFUNC(DSA_free) + RESOLVEFUNC(ERR_error_string) + RESOLVEFUNC(ERR_get_error) +- RESOLVEFUNC(ERR_free_strings) +- RESOLVEFUNC(EVP_CIPHER_CTX_cleanup) +- RESOLVEFUNC(EVP_CIPHER_CTX_init) ++ RESOLVEFUNC(EVP_CIPHER_CTX_new) ++ RESOLVEFUNC(EVP_CIPHER_CTX_free) + RESOLVEFUNC(EVP_CIPHER_CTX_ctrl) + RESOLVEFUNC(EVP_CIPHER_CTX_set_key_length) + RESOLVEFUNC(EVP_CipherInit) ++ RESOLVEFUNC(EVP_CipherInit_ex) + RESOLVEFUNC(EVP_CipherUpdate) + RESOLVEFUNC(EVP_CipherFinal) + RESOLVEFUNC(EVP_des_cbc) + RESOLVEFUNC(EVP_des_ede3_cbc) + RESOLVEFUNC(EVP_rc2_cbc) ++ RESOLVEFUNC(EVP_sha1) + RESOLVEFUNC(EVP_PKEY_assign) + RESOLVEFUNC(EVP_PKEY_set1_RSA) + RESOLVEFUNC(EVP_PKEY_set1_DSA) +@@ -834,9 +1040,8 @@ bool q_resolveOpenSslSymbols() + RESOLVEFUNC(i2t_ASN1_OBJECT) + RESOLVEFUNC(OBJ_obj2txt) + RESOLVEFUNC(OBJ_obj2nid) +-#ifdef SSLEAY_MACROS // ### verify +- RESOLVEFUNC(PEM_ASN1_read_bio) +-#else ++ ++#ifndef SSLEAY_MACROS + RESOLVEFUNC(PEM_read_bio_PrivateKey) + RESOLVEFUNC(PEM_read_bio_DSAPrivateKey) + RESOLVEFUNC(PEM_read_bio_RSAPrivateKey) +@@ -849,7 +1054,8 @@ bool q_resolveOpenSslSymbols() + #ifndef OPENSSL_NO_EC + RESOLVEFUNC(PEM_write_bio_ECPrivateKey) + #endif +-#endif ++#endif // !SSLEAY_MACROS ++ + RESOLVEFUNC(PEM_read_bio_PUBKEY) + RESOLVEFUNC(PEM_read_bio_DSA_PUBKEY) + RESOLVEFUNC(PEM_read_bio_RSA_PUBKEY) +@@ -865,12 +1071,6 @@ bool q_resolveOpenSslSymbols() + RESOLVEFUNC(RAND_status) + RESOLVEFUNC(RSA_new) + RESOLVEFUNC(RSA_free) +- RESOLVEFUNC(sk_new_null) +- RESOLVEFUNC(sk_push) +- RESOLVEFUNC(sk_free) +- RESOLVEFUNC(sk_num) +- RESOLVEFUNC(sk_pop_free) +- RESOLVEFUNC(sk_value) + RESOLVEFUNC(SSL_CIPHER_description) + RESOLVEFUNC(SSL_CIPHER_get_bits) + RESOLVEFUNC(SSL_CTX_check_private_key) +@@ -898,8 +1098,6 @@ bool q_resolveOpenSslSymbols() + RESOLVEFUNC(SSL_get_peer_cert_chain) + RESOLVEFUNC(SSL_get_peer_certificate) + RESOLVEFUNC(SSL_get_verify_result) +- RESOLVEFUNC(SSL_library_init) +- RESOLVEFUNC(SSL_load_error_strings) + RESOLVEFUNC(SSL_new) + RESOLVEFUNC(SSL_ctrl) + RESOLVEFUNC(SSL_read) +@@ -912,7 +1110,6 @@ bool q_resolveOpenSslSymbols() + RESOLVEFUNC(SSL_get1_session) + RESOLVEFUNC(SSL_get_session) + #if OPENSSL_VERSION_NUMBER >= 0x10001000L +- RESOLVEFUNC(SSL_get_ex_new_index) + RESOLVEFUNC(SSL_set_ex_data) + RESOLVEFUNC(SSL_get_ex_data) + #endif +@@ -922,30 +1119,6 @@ bool q_resolveOpenSslSymbols() + RESOLVEFUNC(SSL_CTX_use_psk_identity_hint) + #endif + RESOLVEFUNC(SSL_write) +-#ifndef OPENSSL_NO_SSL2 +- RESOLVEFUNC(SSLv2_client_method) +-#endif +-#ifndef OPENSSL_NO_SSL3_METHOD +- RESOLVEFUNC(SSLv3_client_method) +-#endif +- RESOLVEFUNC(SSLv23_client_method) +- RESOLVEFUNC(TLSv1_client_method) +-#if OPENSSL_VERSION_NUMBER >= 0x10001000L +- RESOLVEFUNC(TLSv1_1_client_method) +- RESOLVEFUNC(TLSv1_2_client_method) +-#endif +-#ifndef OPENSSL_NO_SSL2 +- RESOLVEFUNC(SSLv2_server_method) +-#endif +-#ifndef OPENSSL_NO_SSL3_METHOD +- RESOLVEFUNC(SSLv3_server_method) +-#endif +- RESOLVEFUNC(SSLv23_server_method) +- RESOLVEFUNC(TLSv1_server_method) +-#if OPENSSL_VERSION_NUMBER >= 0x10001000L +- RESOLVEFUNC(TLSv1_1_server_method) +- RESOLVEFUNC(TLSv1_2_server_method) +-#endif + RESOLVEFUNC(X509_NAME_entry_count) + RESOLVEFUNC(X509_NAME_get_entry) + RESOLVEFUNC(X509_NAME_ENTRY_get_data) +@@ -961,12 +1134,12 @@ bool q_resolveOpenSslSymbols() + RESOLVEFUNC(X509_STORE_CTX_get_error) + RESOLVEFUNC(X509_STORE_CTX_get_error_depth) + RESOLVEFUNC(X509_STORE_CTX_get_current_cert) +- RESOLVEFUNC(X509_STORE_CTX_get_chain) + RESOLVEFUNC(X509_cmp) + #ifndef SSLEAY_MACROS + RESOLVEFUNC(X509_dup) + #endif + RESOLVEFUNC(X509_print) ++ RESOLVEFUNC(X509_digest) + RESOLVEFUNC(X509_EXTENSION_get_object) + RESOLVEFUNC(X509_free) + RESOLVEFUNC(X509_get_ext) +@@ -982,20 +1155,11 @@ bool q_resolveOpenSslSymbols() + RESOLVEFUNC(X509_check_issued) + RESOLVEFUNC(X509_get_issuer_name) + RESOLVEFUNC(X509_get_subject_name) ++ RESOLVEFUNC(X509_get_serialNumber) + RESOLVEFUNC(X509_verify_cert) + RESOLVEFUNC(d2i_X509) + RESOLVEFUNC(i2d_X509) +-#ifdef SSLEAY_MACROS +- RESOLVEFUNC(i2d_DSAPrivateKey) +- RESOLVEFUNC(i2d_RSAPrivateKey) +- RESOLVEFUNC(d2i_DSAPrivateKey) +- RESOLVEFUNC(d2i_RSAPrivateKey) +-#endif +- RESOLVEFUNC(OPENSSL_add_all_algorithms_noconf) +- RESOLVEFUNC(OPENSSL_add_all_algorithms_conf) + RESOLVEFUNC(SSL_CTX_load_verify_locations) +- RESOLVEFUNC(SSLeay) +- RESOLVEFUNC(SSLeay_version) + RESOLVEFUNC(i2d_SSL_SESSION) + RESOLVEFUNC(d2i_SSL_SESSION) + #if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG) +@@ -1019,27 +1183,14 @@ bool q_resolveOpenSslSymbols() + RESOLVEFUNC(EC_KEY_new_by_curve_name) + RESOLVEFUNC(EC_KEY_free) + RESOLVEFUNC(EC_get_builtin_curves) +-#if OPENSSL_VERSION_NUMBER >= 0x10002000L +- if (q_SSLeay() >= 0x10002000L) +- RESOLVEFUNC(EC_curve_nist2nid) +-#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L + #endif // OPENSSL_NO_EC + RESOLVEFUNC(PKCS12_parse) + RESOLVEFUNC(d2i_PKCS12_bio) + RESOLVEFUNC(PKCS12_free) + ++ symbolsResolved = true; + delete libs.first; + delete libs.second; +- if (!_q_SSLeay || q_SSLeay() >= 0x10100000L) { +- // OpenSSL 1.1 deprecated and removed SSLeay. We consider a failure to +- // resolve this symbol as a failure to resolve symbols. +- // The right operand of '||' above ... a bit of paranoia. +- qCWarning(lcSsl, "Incompatible version of OpenSSL"); +- return false; +- } +- +- symbolsResolved = true; +- + return true; + } + #endif // QT_CONFIG(library) +diff --git a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h +index b35a895d38..796bf2d4f5 100644 +--- a/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h ++++ b/qtbase/src/network/ssl/qsslsocket_openssl_symbols_p.h +@@ -1,6 +1,6 @@ + /**************************************************************************** + ** +-** Copyright (C) 2016 The Qt Company Ltd. ++** Copyright (C) 2017 The Qt Company Ltd. + ** Copyright (C) 2014 BlackBerry Limited. All rights reserved. + ** Contact: https://www.qt.io/licensing/ + ** +@@ -56,6 +56,7 @@ + #ifndef QSSLSOCKET_OPENSSL_SYMBOLS_P_H + #define QSSLSOCKET_OPENSSL_SYMBOLS_P_H + ++ + // + // W A R N I N G + // ------------- +@@ -215,17 +216,20 @@ QT_BEGIN_NAMESPACE + + #endif // !defined QT_LINKED_OPENSSL + ++#if QT_CONFIG(opensslv11) ++#include "qsslsocket_openssl11_symbols_p.h" ++#else ++#include "qsslsocket_opensslpre11_symbols_p.h" ++#endif // QT_CONFIG ++ + bool q_resolveOpenSslSymbols(); + long q_ASN1_INTEGER_get(ASN1_INTEGER *a); +-unsigned char * q_ASN1_STRING_data(ASN1_STRING *a); + int q_ASN1_STRING_length(ASN1_STRING *a); + int q_ASN1_STRING_to_UTF8(unsigned char **a, ASN1_STRING *b); + long q_BIO_ctrl(BIO *a, int b, long c, void *d); + Q_AUTOTEST_EXPORT int q_BIO_free(BIO *a); +-Q_AUTOTEST_EXPORT BIO *q_BIO_new(BIO_METHOD *a); + BIO *q_BIO_new_mem_buf(void *a, int b); + int q_BIO_read(BIO *a, void *b, int c); +-Q_AUTOTEST_EXPORT BIO_METHOD *q_BIO_s_mem(); + Q_AUTOTEST_EXPORT int q_BIO_write(BIO *a, const void *b, int c); + int q_BN_num_bits(const BIGNUM *a); + #if OPENSSL_VERSION_NUMBER >= 0x10100000L +@@ -247,26 +251,23 @@ BN_ULONG q_BN_mod_word(const BIGNUM *a, BN_ULONG w); + const EC_GROUP* q_EC_KEY_get0_group(const EC_KEY* k); + int q_EC_GROUP_get_degree(const EC_GROUP* g); + #endif +-int q_CRYPTO_num_locks(); +-void q_CRYPTO_set_locking_callback(void (*a)(int, int, const char *, int)); +-void q_CRYPTO_set_id_callback(unsigned long (*a)()); +-void q_CRYPTO_free(void *a); + DSA *q_DSA_new(); + void q_DSA_free(DSA *a); + X509 *q_d2i_X509(X509 **a, const unsigned char **b, long c); + char *q_ERR_error_string(unsigned long a, char *b); + unsigned long q_ERR_get_error(); +-void q_ERR_free_strings(); +-void q_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); +-void q_EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a); ++EVP_CIPHER_CTX *q_EVP_CIPHER_CTX_new(); ++void q_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a); + int q_EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); + int q_EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); + int q_EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, const unsigned char *key, const unsigned char *iv, int enc); ++int q_EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key, const unsigned char *iv, int enc); + int q_EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); + int q_EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + const EVP_CIPHER *q_EVP_des_cbc(); + const EVP_CIPHER *q_EVP_des_ede3_cbc(); + const EVP_CIPHER *q_EVP_rc2_cbc(); ++const EVP_MD *q_EVP_sha1(); + int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c); + Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b); + int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b); +@@ -310,7 +311,7 @@ int q_PEM_write_bio_RSAPrivateKey(BIO *a, RSA *b, const EVP_CIPHER *c, unsigned + int q_PEM_write_bio_ECPrivateKey(BIO *a, EC_KEY *b, const EVP_CIPHER *c, unsigned char *d, + int e, pem_password_cb *f, void *g); + #endif +-#endif ++#endif // SSLEAY_MACROS + Q_AUTOTEST_EXPORT EVP_PKEY *q_PEM_read_bio_PUBKEY(BIO *a, EVP_PKEY **b, pem_password_cb *c, void *d); + DSA *q_PEM_read_bio_DSA_PUBKEY(BIO *a, DSA **b, pem_password_cb *c, void *d); + RSA *q_PEM_read_bio_RSA_PUBKEY(BIO *a, RSA **b, pem_password_cb *c, void *d); +@@ -326,23 +327,10 @@ void q_RAND_seed(const void *a, int b); + int q_RAND_status(); + RSA *q_RSA_new(); + void q_RSA_free(RSA *a); +-int q_sk_num(STACK *a); +-void q_sk_pop_free(STACK *a, void (*b)(void *)); +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L +-_STACK *q_sk_new_null(); +-void q_sk_push(_STACK *st, void *data); +-void q_sk_free(_STACK *a); +-void * q_sk_value(STACK *a, int b); +-#else +-STACK *q_sk_new_null(); +-void q_sk_push(STACK *st, char *data); +-void q_sk_free(STACK *a); +-char * q_sk_value(STACK *a, int b); +-#endif + int q_SSL_accept(SSL *a); + int q_SSL_clear(SSL *a); +-char *q_SSL_CIPHER_description(SSL_CIPHER *a, char *b, int c); +-int q_SSL_CIPHER_get_bits(SSL_CIPHER *a, int *b); ++char *q_SSL_CIPHER_description(const SSL_CIPHER *a, char *b, int c); ++int q_SSL_CIPHER_get_bits(const SSL_CIPHER *a, int *b); + int q_SSL_connect(SSL *a); + int q_SSL_CTX_check_private_key(const SSL_CTX *a); + long q_SSL_CTX_ctrl(SSL_CTX *a, int b, long c, void *d); +@@ -374,8 +362,6 @@ int q_SSL_get_error(SSL *a, int b); + STACK_OF(X509) *q_SSL_get_peer_cert_chain(SSL *a); + X509 *q_SSL_get_peer_certificate(SSL *a); + long q_SSL_get_verify_result(const SSL *a); +-int q_SSL_library_init(); +-void q_SSL_load_error_strings(); + SSL *q_SSL_new(SSL_CTX *a); + long q_SSL_ctrl(SSL *ssl,int cmd, long larg, void *parg); + int q_SSL_read(SSL *a, void *b, int c); +@@ -388,7 +374,6 @@ void q_SSL_SESSION_free(SSL_SESSION *ses); + SSL_SESSION *q_SSL_get1_session(SSL *ssl); + SSL_SESSION *q_SSL_get_session(const SSL *ssl); + #if OPENSSL_VERSION_NUMBER >= 0x10001000L +-int q_SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); + int q_SSL_set_ex_data(SSL *ssl, int idx, void *arg); + void *q_SSL_get_ex_data(const SSL *ssl, int idx); + #endif +@@ -399,49 +384,6 @@ typedef unsigned int (*q_psk_server_callback_t)(SSL *ssl, const char *identity, + void q_SSL_set_psk_server_callback(SSL *ssl, q_psk_server_callback_t callback); + int q_SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint); + #endif // OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK) +-#if OPENSSL_VERSION_NUMBER >= 0x10000000L +-#ifndef OPENSSL_NO_SSL2 +-const SSL_METHOD *q_SSLv2_client_method(); +-#endif +-#ifndef OPENSSL_NO_SSL3_METHOD +-const SSL_METHOD *q_SSLv3_client_method(); +-#endif +-const SSL_METHOD *q_SSLv23_client_method(); +-const SSL_METHOD *q_TLSv1_client_method(); +-const SSL_METHOD *q_TLSv1_1_client_method(); +-const SSL_METHOD *q_TLSv1_2_client_method(); +-#ifndef OPENSSL_NO_SSL2 +-const SSL_METHOD *q_SSLv2_server_method(); +-#endif +-#ifndef OPENSSL_NO_SSL3_METHOD +-const SSL_METHOD *q_SSLv3_server_method(); +-#endif +-const SSL_METHOD *q_SSLv23_server_method(); +-const SSL_METHOD *q_TLSv1_server_method(); +-const SSL_METHOD *q_TLSv1_1_server_method(); +-const SSL_METHOD *q_TLSv1_2_server_method(); +-#else +-#ifndef OPENSSL_NO_SSL2 +-SSL_METHOD *q_SSLv2_client_method(); +-#endif +-#ifndef OPENSSL_NO_SSL3_METHOD +-SSL_METHOD *q_SSLv3_client_method(); +-#endif +-SSL_METHOD *q_SSLv23_client_method(); +-SSL_METHOD *q_TLSv1_client_method(); +-SSL_METHOD *q_TLSv1_1_client_method(); +-SSL_METHOD *q_TLSv1_2_client_method(); +-#ifndef OPENSSL_NO_SSL2 +-SSL_METHOD *q_SSLv2_server_method(); +-#endif +-#ifndef OPENSSL_NO_SSL3_METHOD +-SSL_METHOD *q_SSLv3_server_method(); +-#endif +-SSL_METHOD *q_SSLv23_server_method(); +-SSL_METHOD *q_TLSv1_server_method(); +-SSL_METHOD *q_TLSv1_1_server_method(); +-SSL_METHOD *q_TLSv1_2_server_method(); +-#endif + int q_SSL_write(SSL *a, const void *b, int c); + int q_X509_cmp(X509 *a, X509 *b); + #ifdef SSLEAY_MACROS +@@ -452,6 +394,7 @@ void *q_ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x); + X509 *q_X509_dup(X509 *a); + #endif + void q_X509_print(BIO *a, X509*b); ++int q_X509_digest(const X509 *x509, const EVP_MD *type, unsigned char *md, unsigned int *len); + ASN1_OBJECT *q_X509_EXTENSION_get_object(X509_EXTENSION *a); + void q_X509_free(X509 *a); + X509_EXTENSION *q_X509_get_ext(X509 *a, int b); +@@ -471,6 +414,7 @@ int q_ASN1_STRING_print(BIO *a, ASN1_STRING *b); + int q_X509_check_issued(X509 *a, X509 *b); + X509_NAME *q_X509_get_issuer_name(X509 *a); + X509_NAME *q_X509_get_subject_name(X509 *a); ++ASN1_INTEGER *q_X509_get_serialNumber(X509 *a); + int q_X509_verify_cert(X509_STORE_CTX *ctx); + int q_X509_NAME_entry_count(X509_NAME *a); + X509_NAME_ENTRY *q_X509_NAME_get_entry(X509_NAME *a,int b); +@@ -488,7 +432,6 @@ int q_X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); + int q_X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); + int q_X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); + X509 *q_X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +-STACK_OF(X509) *q_X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); + + // Diffie-Hellman support + DH *q_DH_new(); +@@ -522,34 +465,9 @@ int q_PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + PKCS12 *q_d2i_PKCS12_bio(BIO *bio, PKCS12 **pkcs12); + void q_PKCS12_free(PKCS12 *pkcs12); + +- + #define q_BIO_get_mem_data(b, pp) (int)q_BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp) + #define q_BIO_pending(b) (int)q_BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) +-#ifdef SSLEAY_MACROS +-int q_i2d_DSAPrivateKey(const DSA *a, unsigned char **pp); +-int q_i2d_RSAPrivateKey(const RSA *a, unsigned char **pp); +-RSA *q_d2i_RSAPrivateKey(RSA **a, unsigned char **pp, long length); +-DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length); +-#define q_PEM_read_bio_RSAPrivateKey(bp, x, cb, u) \ +- (RSA *)q_PEM_ASN1_read_bio( \ +- (void *(*)(void**, const unsigned char**, long int))q_d2i_RSAPrivateKey, PEM_STRING_RSA, bp, (void **)x, cb, u) +-#define q_PEM_read_bio_DSAPrivateKey(bp, x, cb, u) \ +- (DSA *)q_PEM_ASN1_read_bio( \ +- (void *(*)(void**, const unsigned char**, long int))q_d2i_DSAPrivateKey, PEM_STRING_DSA, bp, (void **)x, cb, u) +-#define q_PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \ +- PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_RSAPrivateKey,PEM_STRING_RSA,\ +- bp,(char *)x,enc,kstr,klen,cb,u) +-#define q_PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \ +- PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_DSAPrivateKey,PEM_STRING_DSA,\ +- bp,(char *)x,enc,kstr,klen,cb,u) +-#define q_PEM_read_bio_DHparams(bp, dh, cb, u) \ +- (DH *)q_PEM_ASN1_read_bio( \ +- (void *(*)(void**, const unsigned char**, long int))q_d2i_DHparams, PEM_STRING_DHPARAMS, bp, (void **)x, cb, u) +-#endif +-#define q_SSL_CTX_set_options(ctx,op) q_SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL) + #define q_SSL_CTX_set_mode(ctx,op) q_SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) +-#define q_SKM_sk_num(type, st) ((int (*)(const STACK_OF(type) *))q_sk_num)(st) +-#define q_SKM_sk_value(type, st,i) ((type * (*)(const STACK_OF(type) *, int))q_sk_value)(st, i) + #define q_sk_GENERAL_NAME_num(st) q_SKM_sk_num(GENERAL_NAME, (st)) + #define q_sk_GENERAL_NAME_value(st, i) q_SKM_sk_value(GENERAL_NAME, (st), (i)) + #define q_sk_X509_num(st) q_SKM_sk_num(X509, (st)) +@@ -558,18 +476,12 @@ DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length); + #define q_sk_SSL_CIPHER_value(st, i) q_SKM_sk_value(SSL_CIPHER, (st), (i)) + #define q_SSL_CTX_add_extra_chain_cert(ctx,x509) \ + q_SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509) +-#define q_X509_get_notAfter(x) X509_get_notAfter(x) +-#define q_X509_get_notBefore(x) X509_get_notBefore(x) + #define q_EVP_PKEY_assign_RSA(pkey,rsa) q_EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\ + (char *)(rsa)) + #define q_EVP_PKEY_assign_DSA(pkey,dsa) q_EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\ + (char *)(dsa)) + #define q_OpenSSL_add_all_algorithms() q_OPENSSL_add_all_algorithms_conf() +-void q_OPENSSL_add_all_algorithms_noconf(); +-void q_OPENSSL_add_all_algorithms_conf(); + int q_SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath); +-long q_SSLeay(); +-const char *q_SSLeay_version(int type); + int q_i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp); + SSL_SESSION *q_d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length); + +diff --git a/qtbase/src/network/ssl/qsslsocket_opensslpre11.cpp b/qtbase/src/network/ssl/qsslsocket_opensslpre11.cpp +new file mode 100644 +index 0000000000..e51888c5f2 +--- /dev/null ++++ b/qtbase/src/network/ssl/qsslsocket_opensslpre11.cpp +@@ -0,0 +1,424 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2017 The Qt Company Ltd. ++** Copyright (C) 2014 Governikus GmbH & Co. KG ++** Contact: https://www.qt.io/licensing/ ++** ++** This file is part of the QtNetwork module of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see https://www.qt.io/terms-conditions. For further ++** information use the contact form at https://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 3 as published by the Free Software ++** Foundation and appearing in the file LICENSE.LGPL3 included in the ++** packaging of this file. Please review the following information to ++** ensure the GNU Lesser General Public License version 3 requirements ++** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ++** ++** GNU General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU ++** General Public License version 2.0 or (at your option) the GNU General ++** Public license version 3 or any later version approved by the KDE Free ++** Qt Foundation. The licenses are as published by the Free Software ++** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ++** included in the packaging of this file. Please review the following ++** information to ensure the GNU General Public License requirements will ++** be met: https://www.gnu.org/licenses/gpl-2.0.html and ++** https://www.gnu.org/licenses/gpl-3.0.html. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++/**************************************************************************** ++** ++** In addition, as a special exception, the copyright holders listed above give ++** permission to link the code of its release of Qt with the OpenSSL project's ++** "OpenSSL" library (or modified versions of the "OpenSSL" library that use the ++** same license as the original version), and distribute the linked executables. ++** ++** You must comply with the GNU General Public License version 2 in all ++** respects for all of the code used other than the "OpenSSL" code. If you ++** modify this file, you may extend this exception to your version of the file, ++** but you are not obligated to do so. If you do not wish to do so, delete ++** this exception statement from your version of this file. ++** ++****************************************************************************/ ++ ++//#define QT_DECRYPT_SSL_TRAFFIC ++ ++#include "qssl_p.h" ++#include "qsslsocket_openssl_p.h" ++#include "qsslsocket_openssl_symbols_p.h" ++#include "qsslsocket.h" ++#include "qsslkey.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++QT_BEGIN_NAMESPACE ++ ++/* \internal ++ ++ From OpenSSL's thread(3) manual page: ++ ++ OpenSSL can safely be used in multi-threaded applications provided that at ++ least two callback functions are set. ++ ++ locking_function(int mode, int n, const char *file, int line) is needed to ++ perform locking on shared data structures. (Note that OpenSSL uses a ++ number of global data structures that will be implicitly shared ++ whenever multiple threads use OpenSSL.) Multi-threaded ++ applications will crash at random if it is not set. ... ++ ... ++ id_function(void) is a function that returns a thread ID. It is not ++ needed on Windows nor on platforms where getpid() returns a different ++ ID for each thread (most notably Linux) ++*/ ++ ++class QOpenSslLocks ++{ ++public: ++ QOpenSslLocks() ++ : initLocker(QMutex::Recursive), ++ locksLocker(QMutex::Recursive) ++ { ++ QMutexLocker locker(&locksLocker); ++ int numLocks = q_CRYPTO_num_locks(); ++ locks = new QMutex *[numLocks]; ++ memset(locks, 0, numLocks * sizeof(QMutex *)); ++ } ++ ~QOpenSslLocks() ++ { ++ QMutexLocker locker(&locksLocker); ++ for (int i = 0; i < q_CRYPTO_num_locks(); ++i) ++ delete locks[i]; ++ delete [] locks; ++ ++ QSslSocketPrivate::deinitialize(); ++ } ++ QMutex *lock(int num) ++ { ++ QMutexLocker locker(&locksLocker); ++ QMutex *tmp = locks[num]; ++ if (!tmp) ++ tmp = locks[num] = new QMutex(QMutex::Recursive); ++ return tmp; ++ } ++ ++ QMutex *globalLock() ++ { ++ return &locksLocker; ++ } ++ ++ QMutex *initLock() ++ { ++ return &initLocker; ++ } ++ ++private: ++ QMutex initLocker; ++ QMutex locksLocker; ++ QMutex **locks; ++}; ++ ++Q_GLOBAL_STATIC(QOpenSslLocks, openssl_locks) ++ ++extern "C" { ++static void locking_function(int mode, int lockNumber, const char *, int) ++{ ++ QMutex *mutex = openssl_locks()->lock(lockNumber); ++ ++ // Lock or unlock it ++ if (mode & CRYPTO_LOCK) ++ mutex->lock(); ++ else ++ mutex->unlock(); ++} ++static unsigned long id_function() ++{ ++ return (quintptr)QThread::currentThreadId(); ++} ++ ++} // extern "C" ++ ++static void q_OpenSSL_add_all_algorithms_safe() ++{ ++#ifdef Q_OS_WIN ++ // Prior to version 1.0.1m an attempt to call OpenSSL_add_all_algorithms on ++ // Windows could result in 'exit' call from OPENSSL_config (QTBUG-43843). ++ // We can predict this and avoid OPENSSL_add_all_algorithms call. ++ // From OpenSSL docs: ++ // "An application does not need to add algorithms to use them explicitly, ++ // for example by EVP_sha1(). It just needs to add them if it (or any of ++ // the functions it calls) needs to lookup algorithms. ++ // The cipher and digest lookup functions are used in many parts of the ++ // library. If the table is not initialized several functions will ++ // misbehave and complain they cannot find algorithms. This includes the ++ // PEM, PKCS#12, SSL and S/MIME libraries. This is a common query in ++ // the OpenSSL mailing lists." ++ // ++ // Anyway, as a result, we chose not to call this function if it would exit. ++ ++ if (q_SSLeay() < 0x100010DFL) ++ { ++ // Now, before we try to call it, check if an attempt to open config file ++ // will result in exit: ++ if (char *confFileName = q_CONF_get1_default_config_file()) { ++ BIO *confFile = q_BIO_new_file(confFileName, "r"); ++ const auto lastError = q_ERR_peek_last_error(); ++ q_CRYPTO_free(confFileName); ++ if (confFile) { ++ q_BIO_free(confFile); ++ } else { ++ q_ERR_clear_error(); ++ if (ERR_GET_REASON(lastError) == ERR_R_SYS_LIB) { ++ qCWarning(lcSsl, "failed to open openssl.conf file"); ++ return; ++ } ++ } ++ } ++ } ++#endif // Q_OS_WIN ++ ++ q_OpenSSL_add_all_algorithms(); ++} ++ ++ ++/*! ++ \internal ++*/ ++void QSslSocketPrivate::deinitialize() ++{ ++ q_CRYPTO_set_id_callback(0); ++ q_CRYPTO_set_locking_callback(0); ++ q_ERR_free_strings(); ++} ++ ++ ++bool QSslSocketPrivate::ensureLibraryLoaded() ++{ ++ if (!q_resolveOpenSslSymbols()) ++ return false; ++ ++ // Check if the library itself needs to be initialized. ++ QMutexLocker locker(openssl_locks()->initLock()); ++ ++ if (!s_libraryLoaded) { ++ s_libraryLoaded = true; ++ ++ // Initialize OpenSSL. ++ q_CRYPTO_set_id_callback(id_function); ++ q_CRYPTO_set_locking_callback(locking_function); ++ if (q_SSL_library_init() != 1) ++ return false; ++ q_SSL_load_error_strings(); ++ q_OpenSSL_add_all_algorithms_safe(); ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10001000L ++ if (q_SSLeay() >= 0x10001000L) ++ QSslSocketBackendPrivate::s_indexForSSLExtraData = q_SSL_get_ex_new_index(0L, NULL, NULL, NULL, NULL); ++#endif ++ ++ // Initialize OpenSSL's random seed. ++ if (!q_RAND_status()) { ++ qWarning("Random number generator not seeded, disabling SSL support"); ++ return false; ++ } ++ } ++ return true; ++} ++ ++void QSslSocketPrivate::ensureCiphersAndCertsLoaded() ++{ ++ QMutexLocker locker(openssl_locks()->initLock()); ++ if (s_loadedCiphersAndCerts) ++ return; ++ s_loadedCiphersAndCerts = true; ++ ++ resetDefaultCiphers(); ++ resetDefaultEllipticCurves(); ++ ++#if QT_CONFIG(library) ++ //load symbols needed to receive certificates from system store ++#if defined(Q_OS_WIN) ++ HINSTANCE hLib = LoadLibraryW(L"Crypt32"); ++ if (hLib) { ++ ptrCertOpenSystemStoreW = (PtrCertOpenSystemStoreW)GetProcAddress(hLib, "CertOpenSystemStoreW"); ++ ptrCertFindCertificateInStore = (PtrCertFindCertificateInStore)GetProcAddress(hLib, "CertFindCertificateInStore"); ++ ptrCertCloseStore = (PtrCertCloseStore)GetProcAddress(hLib, "CertCloseStore"); ++ if (!ptrCertOpenSystemStoreW || !ptrCertFindCertificateInStore || !ptrCertCloseStore) ++ qCWarning(lcSsl, "could not resolve symbols in crypt32 library"); // should never happen ++ } else { ++ qCWarning(lcSsl, "could not load crypt32 library"); // should never happen ++ } ++#elif defined(Q_OS_QNX) ++ s_loadRootCertsOnDemand = true; ++#elif defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) ++ // check whether we can enable on-demand root-cert loading (i.e. check whether the sym links are there) ++ QList dirs = unixRootCertDirectories(); ++ QStringList symLinkFilter; ++ symLinkFilter << QLatin1String("[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].[0-9]"); ++ for (int a = 0; a < dirs.count(); ++a) { ++ QDirIterator iterator(QLatin1String(dirs.at(a)), symLinkFilter, QDir::Files); ++ if (iterator.hasNext()) { ++ s_loadRootCertsOnDemand = true; ++ break; ++ } ++ } ++#endif ++#endif // QT_CONFIG(library) ++ // if on-demand loading was not enabled, load the certs now ++ if (!s_loadRootCertsOnDemand) ++ setDefaultCaCertificates(systemCaCertificates()); ++#ifdef Q_OS_WIN ++ //Enabled for fetching additional root certs from windows update on windows 6+ ++ //This flag is set false by setDefaultCaCertificates() indicating the app uses ++ //its own cert bundle rather than the system one. ++ //Same logic that disables the unix on demand cert loading. ++ //Unlike unix, we do preload the certificates from the cert store. ++ if ((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) >= QSysInfo::WV_6_0) ++ s_loadRootCertsOnDemand = true; ++#endif ++} ++ ++long QSslSocketPrivate::sslLibraryVersionNumber() ++{ ++ if (!supportsSsl()) ++ return 0; ++ ++ return q_SSLeay(); ++} ++ ++QString QSslSocketPrivate::sslLibraryVersionString() ++{ ++ if (!supportsSsl()) ++ return QString(); ++ ++ const char *versionString = q_SSLeay_version(SSLEAY_VERSION); ++ if (!versionString) ++ return QString(); ++ ++ return QString::fromLatin1(versionString); ++} ++ ++void QSslSocketBackendPrivate::continueHandshake() ++{ ++ Q_Q(QSslSocket); ++ // if we have a max read buffer size, reset the plain socket's to match ++ if (readBufferMaxSize) ++ plainSocket->setReadBufferSize(readBufferMaxSize); ++ ++ if (q_SSL_ctrl((ssl), SSL_CTRL_GET_SESSION_REUSED, 0, NULL)) ++ configuration.peerSessionShared = true; ++ ++#ifdef QT_DECRYPT_SSL_TRAFFIC ++ if (ssl->session && ssl->s3) { ++ const char *mk = reinterpret_cast(ssl->session->master_key); ++ QByteArray masterKey(mk, ssl->session->master_key_length); ++ const char *random = reinterpret_cast(ssl->s3->client_random); ++ QByteArray clientRandom(random, SSL3_RANDOM_SIZE); ++ ++ // different format, needed for e.g. older Wireshark versions: ++// const char *sid = reinterpret_cast(ssl->session->session_id); ++// QByteArray sessionID(sid, ssl->session->session_id_length); ++// QByteArray debugLineRSA("RSA Session-ID:"); ++// debugLineRSA.append(sessionID.toHex().toUpper()); ++// debugLineRSA.append(" Master-Key:"); ++// debugLineRSA.append(masterKey.toHex().toUpper()); ++// debugLineRSA.append("\n"); ++ ++ QByteArray debugLineClientRandom("CLIENT_RANDOM "); ++ debugLineClientRandom.append(clientRandom.toHex().toUpper()); ++ debugLineClientRandom.append(" "); ++ debugLineClientRandom.append(masterKey.toHex().toUpper()); ++ debugLineClientRandom.append("\n"); ++ ++ QString sslKeyFile = QDir::tempPath() + QLatin1String("/qt-ssl-keys"); ++ QFile file(sslKeyFile); ++ if (!file.open(QIODevice::Append)) ++ qCWarning(lcSsl) << "could not open file" << sslKeyFile << "for appending"; ++ if (!file.write(debugLineClientRandom)) ++ qCWarning(lcSsl) << "could not write to file" << sslKeyFile; ++ file.close(); ++ } else { ++ qCWarning(lcSsl, "could not decrypt SSL traffic"); ++ } ++#endif ++ ++ // Cache this SSL session inside the QSslContext ++ if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionSharing)) { ++ if (!sslContextPointer->cacheSession(ssl)) { ++ sslContextPointer.clear(); // we could not cache the session ++ } else { ++ // Cache the session for permanent usage as well ++ if (!(configuration.sslOptions & QSsl::SslOptionDisableSessionPersistence)) { ++ if (!sslContextPointer->sessionASN1().isEmpty()) ++ configuration.sslSession = sslContextPointer->sessionASN1(); ++ configuration.sslSessionTicketLifeTimeHint = sslContextPointer->sessionTicketLifeTimeHint(); ++ } ++ } ++ } ++ ++#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_NEXTPROTONEG) ++ ++ configuration.nextProtocolNegotiationStatus = sslContextPointer->npnContext().status; ++ if (sslContextPointer->npnContext().status == QSslConfiguration::NextProtocolNegotiationUnsupported) { ++ // we could not agree -> be conservative and use HTTP/1.1 ++ configuration.nextNegotiatedProtocol = QByteArrayLiteral("http/1.1"); ++ } else { ++ const unsigned char *proto = 0; ++ unsigned int proto_len = 0; ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L ++ if (q_SSLeay() >= 0x10002000L) { ++ q_SSL_get0_alpn_selected(ssl, &proto, &proto_len); ++ if (proto_len && mode == QSslSocket::SslClientMode) { ++ // Client does not have a callback that sets it ... ++ configuration.nextProtocolNegotiationStatus = QSslConfiguration::NextProtocolNegotiationNegotiated; ++ } ++ } ++ ++ if (!proto_len) { // Test if NPN was more lucky ... ++#else ++ { ++#endif ++ q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len); ++ } ++ ++ if (proto_len) ++ configuration.nextNegotiatedProtocol = QByteArray(reinterpret_cast(proto), proto_len); ++ else ++ configuration.nextNegotiatedProtocol.clear(); ++ } ++#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ... ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10002000L ++ if (q_SSLeay() >= 0x10002000L && mode == QSslSocket::SslClientMode) { ++ EVP_PKEY *key; ++ if (q_SSL_get_server_tmp_key(ssl, &key)) ++ configuration.ephemeralServerKey = QSslKey(key, QSsl::PublicKey); ++ } ++#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L ... ++ ++ connectionEncrypted = true; ++ emit q->encrypted(); ++ if (autoStartHandshake && pendingClose) { ++ pendingClose = false; ++ q->disconnectFromHost(); ++ } ++} ++ ++QT_END_NAMESPACE +diff --git a/qtbase/src/network/ssl/ssl.pri b/qtbase/src/network/ssl/ssl.pri +index d2b0c2d60d..2783effaf1 100644 +--- a/qtbase/src/network/ssl/ssl.pri ++++ b/qtbase/src/network/ssl/ssl.pri +@@ -60,13 +60,25 @@ qtConfig(ssl) { + HEADERS += ssl/qsslcontext_openssl_p.h \ + ssl/qsslsocket_openssl_p.h \ + ssl/qsslsocket_openssl_symbols_p.h +- SOURCES += ssl/qsslcertificate_openssl.cpp \ +- ssl/qsslcontext_openssl.cpp \ ++ SOURCES += ssl/qsslsocket_openssl_symbols.cpp \ + ssl/qssldiffiehellmanparameters_openssl.cpp \ ++ ssl/qsslcertificate_openssl.cpp \ + ssl/qsslellipticcurve_openssl.cpp \ + ssl/qsslkey_openssl.cpp \ + ssl/qsslsocket_openssl.cpp \ +- ssl/qsslsocket_openssl_symbols.cpp ++ ssl/qsslcontext_openssl.cpp ++ ++ qtConfig(opensslv11) { ++ HEADERS += ssl/qsslsocket_openssl11_symbols_p.h ++ SOURCES += ssl/qsslsocket_openssl11.cpp \ ++ ssl/qsslcontext_openssl11.cpp ++ ++ QMAKE_CXXFLAGS += -DOPENSSL_API_COMPAT=0x10100000L ++ } else { ++ HEADERS += ssl/qsslsocket_opensslpre11_symbols_p.h ++ SOURCES += ssl/qsslsocket_opensslpre11.cpp \ ++ ssl/qsslcontext_opensslpre11.cpp ++ } + + darwin:SOURCES += ssl/qsslsocket_mac_shared.cpp + diff --git a/package/lean/qt5/files/qmake.conf b/package/lean/qt5/src/qtbase/mkspecs/linux-openwrt-g++/qmake.conf similarity index 66% rename from package/lean/qt5/files/qmake.conf rename to package/lean/qt5/src/qtbase/mkspecs/linux-openwrt-g++/qmake.conf index 20491903ac..8aec5b857f 100644 --- a/package/lean/qt5/files/qmake.conf +++ b/package/lean/qt5/src/qtbase/mkspecs/linux-openwrt-g++/qmake.conf @@ -14,20 +14,18 @@ include(../common/g++-unix.conf) QMAKE_CC = $(TARGET_CROSS)gcc QMAKE_CXX = $(TARGET_CROSS)g++ -QMAKE_CFLAGS += $$(TARGET_CFLAGS) -QMAKE_CXXFLAGS += $$(TARGET_CXXFLAGS) -QMAKE_LFLAGS += $$(TARGET_LDFLAGS) +QMAKE_CFLAGS += $(TARGET_CFLAGS) +QMAKE_CXXFLAGS += $(TARGET_CXXFLAGS) +QMAKE_LFLAGS += $(TARGET_LDFLAGS) -QMAKE_LINK_C = $$QMAKE_CC -QMAKE_LINK_C_SHLIB = $$QMAKE_CC -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX +QMAKE_LINK_C = $(TARGET_CROSS)gcc +QMAKE_LINK_C_SHLIB = $(TARGET_CROSS)gcc +QMAKE_LINK = $(TARGET_CROSS)g++ +QMAKE_LINK_SHLIB = $(TARGET_CROSS)g++ # modifications to linux.conf QMAKE_AR = $(TARGET_CROSS)ar cqs QMAKE_OBJCOPY = $(TARGET_CROSS)objcopy QMAKE_NM = $(TARGET_CROSS)nm -P QMAKE_STRIP = $(TARGET_CROSS)strip - - load(qt_config) diff --git a/package/lean/qt5/src/qtbase/mkspecs/linux-openwrt-g++/qplatformdefs.h b/package/lean/qt5/src/qtbase/mkspecs/linux-openwrt-g++/qplatformdefs.h new file mode 100644 index 0000000000..02e77c9a37 --- /dev/null +++ b/package/lean/qt5/src/qtbase/mkspecs/linux-openwrt-g++/qplatformdefs.h @@ -0,0 +1,9 @@ +#include "../linux-g++/qplatformdefs.h" + +#undef QT_SOCKLEN_T + +#if defined(__GLIBC__) && (__GLIBC__ < 2) +#define QT_SOCKLEN_T int +#else +#define QT_SOCKLEN_T socklen_t +#endif diff --git a/package/lienol/ipt2socks/Makefile b/package/lienol/ipt2socks/Makefile new file mode 100644 index 0000000000..3e9e281fb8 --- /dev/null +++ b/package/lienol/ipt2socks/Makefile @@ -0,0 +1,48 @@ +# +# Copyright (C) 2014 OpenWrt-dist +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=ipt2socks +PKG_VERSION:=1.0.1 +PKG_RELEASE:=2 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/zfl9/ipt2socks.git +PKG_SOURCE_VERSION:=b9bd7d888f2f95a6d7306030c8a5e252732dc451 +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)/$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION) + +include $(INCLUDE_DIR)/package.mk + +define Package/ipt2socks + SECTION:=net + CATEGORY:=Network + TITLE:=Utility for converting iptables (REDIRECT/TPROXY) to SOCKS5 + URL:=https://github.com/zfl9/ipt2socks + DEPENDS:=+libuv +endef + +define Package/ipt2socks/description +Utility for converting iptables (REDIRECT/TPROXY) to SOCKS5. +endef + +define Package/ipt2socks/conffiles +/etc/config/ipt2socks +endef + +#MAKE_FLAGS += INCLUDES="-I$(STAGING_DIR)/usr/include" +#MAKE_FLAGS += LDFLAGS="-L$(STAGING_DIR)/usr/lib" +MAKE_FLAGS += LIBS="-l:libuv_a.a" + +define Package/ipt2socks/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/ipt2socks $(1)/usr/bin +endef + +$(eval $(call BuildPackage,ipt2socks)) diff --git a/package/lienol/trojan/Makefile b/package/lienol/trojan/Makefile new file mode 100644 index 0000000000..c17c136ed6 --- /dev/null +++ b/package/lienol/trojan/Makefile @@ -0,0 +1,66 @@ +# +# Copyright (C) 2018-2019 wongsyrone +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=trojan +PKG_VERSION:=1.13.0 +PKG_RELEASE:=2 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/trojan-gfw/trojan.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=98533aa1003979862763f4225266de78581e40bc +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz + +CMAKE_INSTALL:=1 +PKG_BUILD_PARALLEL:=0 +PKG_BUILD_DEPENDS:=openssl + +PKG_LICENSE:=GPL-3.0 +PKG_MAINTAINER:=GreaterFire + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +TARGET_CXXFLAGS += -Wall -Wextra +TARGET_CXXFLAGS += $(FPIC) + +# LTO +TARGET_CXXFLAGS += -flto +TARGET_LDFLAGS += -flto + +# CXX standard +TARGET_CXXFLAGS += -std=c++11 +TARGET_CXXFLAGS := $(filter-out -O%,$(TARGET_CXXFLAGS)) -O3 +TARGET_CXXFLAGS += -ffunction-sections -fdata-sections +TARGET_LDFLAGS += -Wl,--gc-sections + +CMAKE_OPTIONS += \ + -DENABLE_MYSQL=OFF \ + -DENABLE_SSL_KEYLOG=ON \ + -DENABLE_NAT=ON \ + -DFORCE_TCP_FASTOPEN=OFF \ + -DSYSTEMD_SERVICE=OFF \ + -DOPENSSL_USE_STATIC_LIBS=FALSE \ + -DBoost_DEBUG=OFF \ + -DBoost_NO_BOOST_CMAKE=ON + +define Package/trojan + SECTION:=net + CATEGORY:=Network + TITLE:=An unidentifiable mechanism that helps you bypass GFW + URL:=https://github.com/trojan-gfw/trojan + DEPENDS:=+libpthread +libstdcpp +libopenssl \ + +boost +boost-system +boost-program_options +boost-date_time +endef + +define Package/trojan/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/trojan $(1)/usr/sbin/trojan +endef + +$(eval $(call BuildPackage,trojan)) diff --git a/package/lienol/trojan/patches/001-force-openssl-version.patch b/package/lienol/trojan/patches/001-force-openssl-version.patch new file mode 100644 index 0000000000..0a7291261b --- /dev/null +++ b/package/lienol/trojan/patches/001-force-openssl-version.patch @@ -0,0 +1,11 @@ +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -43,7 +43,7 @@ if(MSVC) + add_definitions(-DBOOST_DATE_TIME_NO_LIB) + endif() + +-find_package(OpenSSL 1.0.2 REQUIRED) ++find_package(OpenSSL 1.1.1 REQUIRED) + include_directories(${OPENSSL_INCLUDE_DIR}) + target_link_libraries(trojan ${OPENSSL_LIBRARIES}) + if(OPENSSL_VERSION VERSION_GREATER_EQUAL 1.1.1)