[tor-commits] [tor-browser] 09/311: Bug 1749501 - Revert bug 1392272, r=dragana a=RyanVM, dsmith
gitolite role
git at cupani.torproject.org
Tue Apr 26 15:26:49 UTC 2022
This is an automated email from the git hooks/post-receive script.
pierov pushed a commit to branch geckoview-99.0.1-11.0-1
in repository tor-browser.
commit fff38e7acb7916c7e9113eae5b52d2ab816a21db
Author: Kershaw Chang <kershaw at mozilla.com>
AuthorDate: Thu Jan 13 01:24:49 2022 +0000
Bug 1749501 - Revert bug 1392272, r=dragana a=RyanVM,dsmith
Differential Revision: https://phabricator.services.mozilla.com/D135702
---
.../windowsproxy/nsWindowsSystemProxySettings.cpp | 475 ++++-----------------
1 file changed, 93 insertions(+), 382 deletions(-)
diff --git a/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp b/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp
index 8ac245f09ee8e..7921cb60a242f 100644
--- a/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp
+++ b/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp
@@ -6,52 +6,30 @@
#include <windows.h>
#include <ras.h>
#include <wininet.h>
-#include <functional>
#include "mozilla/ArrayUtils.h"
#include "mozilla/Attributes.h"
-#include "mozilla/Atomics.h"
#include "nsISystemProxySettings.h"
#include "mozilla/Components.h"
-#include "mozilla/Mutex.h"
-#include "mozilla/Services.h"
#include "mozilla/ProfilerLabels.h"
-#include "mozilla/StaticPrefs_network.h"
-#include "mozilla/Tokenizer.h"
-#include "mozilla/Unused.h"
-#include "nsComponentManagerUtils.h"
-#include "nsIObserver.h"
-#include "nsIObserverService.h"
-#include "nsIWindowsRegKey.h"
#include "nsPrintfCString.h"
#include "nsNetCID.h"
#include "nsThreadUtils.h"
#include "prnetdb.h"
#include "ProxyUtils.h"
-#include "ProxyConfig.h"
-using namespace mozilla::net;
-
-class nsWindowsSystemProxySettings : public nsISystemProxySettings {
+class nsWindowsSystemProxySettings final : public nsISystemProxySettings {
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSISYSTEMPROXYSETTINGS
nsWindowsSystemProxySettings(){};
- virtual nsresult Init() { return NS_OK; }
- protected:
- virtual ~nsWindowsSystemProxySettings() = default;
+ private:
+ ~nsWindowsSystemProxySettings(){};
bool MatchOverride(const nsACString& aHost);
- bool MatchOverrideInternal(const nsACString& aHost,
- const nsACString& aOverrideRule);
bool PatternMatch(const nsACString& aHost, const nsACString& aOverride);
- nsresult ReadProxyRules(
- uint32_t aOptions,
- const std::function<bool(uint32_t aFlags)>& aFlagsHandler,
- const std::function<void(const nsACString& aRule, bool& aContinue)>&
- aRuleHandler);
};
NS_IMPL_ISUPPORTS(nsWindowsSystemProxySettings, nsISystemProxySettings)
@@ -65,6 +43,18 @@ nsWindowsSystemProxySettings::GetMainThreadOnly(bool* aMainThreadOnly) {
return NS_OK;
}
+static void SetProxyResult(const char* aType, const nsACString& aHostPort,
+ nsACString& aResult) {
+ aResult.AssignASCII(aType);
+ aResult.Append(' ');
+ aResult.Append(aHostPort);
+}
+
+static void SetProxyResultDirect(nsACString& aResult) {
+ // For whatever reason, a proxy is not to be used.
+ aResult.AssignLiteral("DIRECT");
+}
+
static nsresult ReadInternetOption(uint32_t aOption, uint32_t& aFlags,
nsAString& aValue) {
// Bug 1366133: InternetGetConnectedStateExW() may cause hangs
@@ -103,82 +93,47 @@ static nsresult ReadInternetOption(uint32_t aOption, uint32_t& aFlags,
return NS_OK;
}
-bool nsWindowsSystemProxySettings::MatchOverrideInternal(
- const nsACString& aHost, const nsACString& aOverrideRule) {
- // Windows formats its proxy override list in the form:
- // server;server;server where 'server' is a server name pattern or IP
- // address, or "<local>". "<local>" must be translated to
- // "localhost;127.0.0.1".
- // In a server name pattern, a '*' character matches any substring and
- // all other characters must match themselves; the whole pattern must match
- // the whole hostname.
- nsAutoCString host(aHost);
- if (aOverrideRule.EqualsLiteral("<local>")) {
- PRNetAddr addr;
- bool isIpAddr = (PR_StringToNetAddr(host.get(), &addr) == PR_SUCCESS);
-
- // Don't use proxy for local hosts (plain hostname, no dots)
- if (!isIpAddr && !host.Contains('.')) {
- return true;
- }
-
- if (host.EqualsLiteral("127.0.0.1") || host.EqualsLiteral("::1")) {
- return true;
- }
- } else if (PatternMatch(host, aOverrideRule)) {
- return true;
- }
-
- return false;
-}
-
bool nsWindowsSystemProxySettings::MatchOverride(const nsACString& aHost) {
- nsAutoCString host(aHost);
- bool foundMatch = false;
-
- auto flagHandler = [](uint32_t aFlags) { return true; };
- auto ruleHandler = [&](const nsACString& aOverrideRule, bool& aContinue) {
- foundMatch = MatchOverrideInternal(aHost, aOverrideRule);
- if (foundMatch) {
- aContinue = false;
- }
- };
-
- ReadProxyRules(INTERNET_PER_CONN_PROXY_BYPASS, flagHandler, ruleHandler);
- return foundMatch;
-}
-
-nsresult nsWindowsSystemProxySettings::ReadProxyRules(
- uint32_t aOptions,
- const std::function<bool(uint32_t aFlags)>& aFlagsHandler,
- const std::function<void(const nsACString& aRule, bool& aContinue)>&
- aRuleHandler) {
+ nsresult rv;
uint32_t flags = 0;
nsAutoString buf;
- nsresult rv = ReadInternetOption(aOptions, flags, buf);
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- if (!aFlagsHandler(flags)) {
- return NS_ERROR_FAILURE;
- }
+ rv = ReadInternetOption(INTERNET_PER_CONN_PROXY_BYPASS, flags, buf);
+ if (NS_FAILED(rv)) return false;
NS_ConvertUTF16toUTF8 cbuf(buf);
+ nsAutoCString host(aHost);
int32_t start = 0;
int32_t end = cbuf.Length();
+
+ // Windows formats its proxy override list in the form:
+ // server;server;server where 'server' is a server name pattern or IP
+ // address, or "<local>". "<local>" must be translated to
+ // "localhost;127.0.0.1".
+ // In a server name pattern, a '*' character matches any substring and
+ // all other characters must match themselves; the whole pattern must match
+ // the whole hostname.
while (true) {
int32_t delimiter = cbuf.FindCharInSet(" ;", start);
if (delimiter == -1) delimiter = end;
if (delimiter != start) {
- const nsAutoCString rule(Substring(cbuf, start, delimiter - start));
- bool continueProcessing = false;
- aRuleHandler(rule, continueProcessing);
- if (!continueProcessing) {
- return NS_OK;
+ const nsAutoCString override(Substring(cbuf, start, delimiter - start));
+ if (override.EqualsLiteral("<local>")) {
+ PRNetAddr addr;
+ bool isIpAddr = (PR_StringToNetAddr(host.get(), &addr) == PR_SUCCESS);
+
+ // Don't use proxy for local hosts (plain hostname, no dots)
+ if (!isIpAddr && !host.Contains('.')) {
+ return true;
+ }
+
+ if (host.EqualsLiteral("127.0.0.1") || host.EqualsLiteral("::1")) {
+ return true;
+ }
+ } else if (PatternMatch(host, override)) {
+ return true;
}
}
@@ -186,7 +141,7 @@ nsresult nsWindowsSystemProxySettings::ReadProxyRules(
start = ++delimiter;
}
- return NS_OK;
+ return false;
}
bool nsWindowsSystemProxySettings::PatternMatch(const nsACString& aHost,
@@ -215,322 +170,78 @@ nsresult nsWindowsSystemProxySettings::GetProxyForURI(const nsACString& aSpec,
const nsACString& aHost,
const int32_t aPort,
nsACString& aResult) {
- auto flagHandler = [&](uint32_t aFlags) {
- if (!(aFlags & PROXY_TYPE_PROXY)) {
- ProxyConfig::SetProxyResultDirect(aResult);
- return false;
- }
+ nsresult rv;
+ uint32_t flags = 0;
+ nsAutoString buf;
- if (MatchOverride(aHost)) {
- ProxyConfig::SetProxyResultDirect(aResult);
- return false;
- }
+ rv = ReadInternetOption(INTERNET_PER_CONN_PROXY_SERVER, flags, buf);
+ if (NS_FAILED(rv) || !(flags & PROXY_TYPE_PROXY)) {
+ SetProxyResultDirect(aResult);
+ return NS_OK;
+ }
- return true;
- };
+ if (MatchOverride(aHost)) {
+ SetProxyResultDirect(aResult);
+ return NS_OK;
+ }
+
+ NS_ConvertUTF16toUTF8 cbuf(buf);
constexpr auto kSocksPrefix = "socks="_ns;
nsAutoCString prefix;
ToLowerCase(aScheme, prefix);
+
prefix.Append('=');
nsAutoCString specificProxy;
nsAutoCString defaultProxy;
nsAutoCString socksProxy;
+ int32_t start = 0;
+ int32_t end = cbuf.Length();
- auto ruleHandler = [&](const nsACString& aRule, bool& aContinue) {
- const nsCString proxy(aRule);
- aContinue = true;
- if (proxy.FindChar('=') == -1) {
- // If a proxy name is listed by itself, it is used as the
- // default proxy for any protocols that do not have a specific
- // proxy specified.
- // (http://msdn.microsoft.com/en-us/library/aa383996%28VS.85%29.aspx)
- defaultProxy = proxy;
- } else if (proxy.Find(prefix) == 0) {
- // To list a proxy for a specific protocol, the string must
- // follow the format "<protocol>=<protocol>://<proxy_name>".
- // (http://msdn.microsoft.com/en-us/library/aa383996%28VS.85%29.aspx)
- specificProxy = Substring(proxy, prefix.Length());
- aContinue = false;
- } else if (proxy.Find(kSocksPrefix) == 0) {
- // SOCKS proxy.
- socksProxy = Substring(proxy, kSocksPrefix.Length()); // "socks=" length.
- }
- };
-
- nsresult rv =
- ReadProxyRules(INTERNET_PER_CONN_PROXY_SERVER, flagHandler, ruleHandler);
- if (NS_FAILED(rv)) {
- ProxyConfig::SetProxyResultDirect(aResult);
- return rv;
- }
-
- ProxyConfig::ProxyStrToResult(specificProxy, defaultProxy, socksProxy,
- aResult);
- return NS_OK;
-}
-
-class WindowsSystemProxySettingsAsync final
- : public nsWindowsSystemProxySettings,
- public nsIObserver {
- public:
- NS_DECL_ISUPPORTS_INHERITED
- NS_DECL_NSISYSTEMPROXYSETTINGS
- NS_DECL_NSIOBSERVER
-
- WindowsSystemProxySettingsAsync();
- nsresult Init() override;
-
- private:
- virtual ~WindowsSystemProxySettingsAsync();
- void ThreadFunc();
- void OnProxyConfigChangedInternal();
-
- ProxyConfig mConfig;
- nsCOMPtr<nsIThread> mBackgroundThread;
- mozilla::Mutex mLock{"WindowsSystemProxySettingsAsync"};
- mozilla::Atomic<bool> mInited{false};
- mozilla::Atomic<bool> mTerminated{false};
-};
-
-NS_IMPL_ISUPPORTS_INHERITED(WindowsSystemProxySettingsAsync,
- nsWindowsSystemProxySettings, nsIObserver);
-
-WindowsSystemProxySettingsAsync::WindowsSystemProxySettingsAsync() = default;
-
-WindowsSystemProxySettingsAsync::~WindowsSystemProxySettingsAsync() = default;
-
-nsresult WindowsSystemProxySettingsAsync::Init() {
- nsCOMPtr<nsIObserverService> observerService =
- mozilla::services::GetObserverService();
- if (!observerService) {
- return NS_ERROR_FAILURE;
- }
- observerService->AddObserver(this, "xpcom-shutdown-threads", false);
-
- nsCOMPtr<nsIThread> thread;
- if (NS_FAILED(NS_NewNamedThread("System Proxy", getter_AddRefs(thread)))) {
- NS_WARNING("NS_NewNamedThread failed!");
- return NS_ERROR_FAILURE;
- }
-
- mBackgroundThread = std::move(thread);
-
- nsCOMPtr<nsIRunnable> event = mozilla::NewRunnableMethod(
- "WindowsSystemProxySettingsAsync::ThreadFunc", this,
- &WindowsSystemProxySettingsAsync::ThreadFunc);
- return mBackgroundThread->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
-}
-
-NS_IMETHODIMP
-WindowsSystemProxySettingsAsync::Observe(nsISupports* aSubject,
- const char* aTopic,
- const char16_t* aData) {
- if (!strcmp(aTopic, "xpcom-shutdown-threads")) {
- if (mBackgroundThread) {
- mTerminated = true;
- nsCOMPtr<nsIThread> thread;
- {
- mozilla::MutexAutoLock lock(mLock);
- thread = mBackgroundThread.get();
- mBackgroundThread = nullptr;
- }
- MOZ_ALWAYS_SUCCEEDS(thread->Shutdown());
- }
- }
- return NS_OK;
-}
-
-void WindowsSystemProxySettingsAsync::ThreadFunc() {
- nsresult rv;
- nsCOMPtr<nsIWindowsRegKey> regKey =
- do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
- if (NS_FAILED(rv)) {
- return;
- }
-
- rv = regKey->Open(
- nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
- u"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"_ns,
- nsIWindowsRegKey::ACCESS_READ);
- if (NS_FAILED(rv)) {
- return;
- }
-
- OnProxyConfigChangedInternal();
-
- rv = regKey->StartWatching(true);
- if (NS_FAILED(rv)) {
- return;
- }
-
- mInited = true;
-
- while (!mTerminated) {
- bool changed = false;
- regKey->HasChanged(&changed);
- if (changed) {
- OnProxyConfigChangedInternal();
- }
- }
-}
-
-void WindowsSystemProxySettingsAsync::OnProxyConfigChangedInternal() {
- ProxyConfig config;
-
- // PAC
- nsAutoCString pacUrl;
- if (NS_SUCCEEDED(GetPACURI(pacUrl))) {
- config.SetPACUrl(pacUrl);
- }
+ while (true) {
+ int32_t delimiter = cbuf.FindCharInSet(" ;", start);
+ if (delimiter == -1) delimiter = end;
- // proxies
- auto flagHandler = [&](uint32_t aFlags) {
- if (!(aFlags & PROXY_TYPE_PROXY)) {
- return false;
- }
- return true;
- };
-
- // The format of input string is like: scheme=host:port, e.g.
- // "http=127.0.0.1:3128".
- auto processProxyStr = [](const nsCString& aInput,
- ProxyServer::ProxyType& aOutType,
- nsACString& aOutHost, int32_t& aOutPort) {
- aOutType = ProxyServer::ProxyType::DEFAULT;
- aOutHost = EmptyCString();
- aOutPort = -1;
-
- mozilla::Tokenizer t(aInput);
- mozilla::Tokenizer::Token token;
- // skip over spaces
- t.SkipWhites();
- t.Record();
-
- bool parsingIPv6 = false;
- bool parsingPort = false;
- while (t.Next(token)) {
- if (token.Equals(mozilla::Tokenizer::Token::EndOfFile())) {
- if (aOutHost.IsEmpty()) {
- t.Claim(aOutHost);
- }
+ if (delimiter != start) {
+ const nsAutoCString proxy(Substring(cbuf, start, delimiter - start));
+ if (proxy.FindChar('=') == -1) {
+ // If a proxy name is listed by itself, it is used as the
+ // default proxy for any protocols that do not have a specific
+ // proxy specified.
+ // (http://msdn.microsoft.com/en-us/library/aa383996%28VS.85%29.aspx)
+ defaultProxy = proxy;
+ } else if (proxy.Find(prefix) == 0) {
+ // To list a proxy for a specific protocol, the string must
+ // follow the format "<protocol>=<protocol>://<proxy_name>".
+ // (http://msdn.microsoft.com/en-us/library/aa383996%28VS.85%29.aspx)
+ specificProxy = Substring(proxy, prefix.Length());
break;
- }
-
- if (token.Equals(mozilla::Tokenizer::Token::Char('='))) {
- nsAutoCString typeStr;
- t.Claim(typeStr);
- aOutType = ProxyConfig::ToProxyType(typeStr.get());
- t.Record();
- }
-
- if (token.Equals(mozilla::Tokenizer::Token::Char('['))) {
- parsingIPv6 = true;
- continue;
- }
-
- if (!parsingIPv6 && token.Equals(mozilla::Tokenizer::Token::Char(':'))) {
- // Port is starting. Claim the previous as host.
- t.Claim(aOutHost);
- t.Record();
- parsingPort = true;
- continue;
- }
-
- if (token.Equals(mozilla::Tokenizer::Token::Char(']'))) {
- parsingIPv6 = false;
- continue;
+ } else if (proxy.Find(kSocksPrefix) == 0) {
+ // SOCKS proxy.
+ socksProxy =
+ Substring(proxy, kSocksPrefix.Length()); // "socks=" length.
}
}
- if (parsingPort) {
- nsAutoCString portStr;
- t.Claim(portStr);
- nsresult rv = NS_OK;
- aOutPort = portStr.ToInteger(&rv);
- if (NS_FAILED(rv)) {
- aOutPort = -1;
- }
- }
- };
-
- auto ruleHandler = [&](const nsACString& aRule, bool& aContinue) {
- const nsCString proxy(aRule);
- aContinue = true;
- ProxyServer::ProxyType type;
- nsCString host;
- int32_t port = -1;
- processProxyStr(proxy, type, host, port);
- if (!host.IsEmpty()) {
- ProxyServer server(type, host, port);
- config.Rules().mProxyServers[server.Type()] = std::move(server);
- }
- };
-
- // Note that reading the proxy settings from registry directly is not
- // documented by Microsoft, so doing it could be risky. We still use system
- // API to read proxy settings for safe.
- ReadProxyRules(INTERNET_PER_CONN_PROXY_SERVER, flagHandler, ruleHandler);
-
- auto bypassRuleHandler = [&](const nsACString& aOverrideRule,
- bool& aContinue) {
- aContinue = true;
- config.ByPassRules().mExceptions.AppendElement(aOverrideRule);
- };
-
- auto dummyHandler = [](uint32_t aFlags) { return true; };
- ReadProxyRules(INTERNET_PER_CONN_PROXY_BYPASS, dummyHandler,
- bypassRuleHandler);
-
- {
- mozilla::MutexAutoLock lock(mLock);
- mConfig = std::move(config);
- }
-}
-
-NS_IMETHODIMP
-WindowsSystemProxySettingsAsync::GetMainThreadOnly(bool* aMainThreadOnly) {
- return nsWindowsSystemProxySettings::GetMainThreadOnly(aMainThreadOnly);
-}
-
-NS_IMETHODIMP WindowsSystemProxySettingsAsync::GetPACURI(nsACString& aResult) {
- AUTO_PROFILER_LABEL("WindowsSystemProxySettingsAsync::GetPACURI", OTHER);
- mozilla::MutexAutoLock lock(mLock);
- aResult.Assign(mConfig.PACUrl());
- return NS_OK;
-}
-
-NS_IMETHODIMP WindowsSystemProxySettingsAsync::GetProxyForURI(
- const nsACString& aSpec, const nsACString& aScheme, const nsACString& aHost,
- const int32_t aPort, nsACString& aResult) {
- // Fallback to nsWindowsSystemProxySettings::GetProxyForURI if we failed to
- // monitor the change of registry keys.
- if (!mInited) {
- return nsWindowsSystemProxySettings::GetProxyForURI(aSpec, aScheme, aHost,
- aPort, aResult);
+ if (delimiter == end) break;
+ start = ++delimiter;
}
- mozilla::MutexAutoLock lock(mLock);
+ if (!specificProxy.IsEmpty())
+ SetProxyResult("PROXY", specificProxy,
+ aResult); // Protocol-specific proxy.
+ else if (!defaultProxy.IsEmpty())
+ SetProxyResult("PROXY", defaultProxy, aResult); // Default proxy.
+ else if (!socksProxy.IsEmpty())
+ SetProxyResult("SOCKS", socksProxy, aResult); // SOCKS proxy.
+ else
+ SetProxyResultDirect(aResult); // Direct connection.
- for (const auto& bypassRule : mConfig.ByPassRules().mExceptions) {
- if (MatchOverrideInternal(aHost, bypassRule)) {
- ProxyConfig::SetProxyResultDirect(aResult);
- return NS_OK;
- }
- }
-
- mConfig.GetProxyString(aScheme, aResult);
return NS_OK;
}
NS_IMPL_COMPONENT_FACTORY(nsWindowsSystemProxySettings) {
- auto settings =
- mozilla::StaticPrefs::network_proxy_detect_system_proxy_changes()
- ? mozilla::MakeRefPtr<WindowsSystemProxySettingsAsync>()
- : mozilla::MakeRefPtr<nsWindowsSystemProxySettings>();
- if (NS_SUCCEEDED(settings->Init())) {
- return settings.forget().downcast<nsISupports>();
- }
- return nullptr;
+ return mozilla::MakeAndAddRef<nsWindowsSystemProxySettings>()
+ .downcast<nsISupports>();
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the tor-commits
mailing list