forked from mirrors/gecko-dev
Initially reported and discussed in Bug 610896.
The simple solution of just flipping the pref `network.proxy.socks_remote_dns`
is risky due to potentially breaking SOCKS4 proxy users. Proxying
DNS on SOCKS4 isn't supported. Therefore we speak the incompatible
SOCKS4a protocol when `socks_remote_dns` is enabled, potentially
breaking users setup.
To keep backwards compatibility on SOCKS4 proxy users, that don't have
SOCKS4a support, the pref `network.proxy.socks_remote_dns` is split into
two prefs:
* `network.proxy.socks_remote_dns`: remote DNS for SOCKS4
* `network.proxy.socks5_remote_dns`: remote DNS for SOCKS5.
This way we proxy DNS by default on SOCKS5 while keeping user settings
on SOCKS4. This is a similar approach to the one described in
[Bug 610896 comment 17].
Proxying DNS in SOCKS4 by default is desireable (See [Bug 610896 comment 11]),
but out of scope for this patch. [Telemetry] on proxy usage by socks
version indicated that changing the default for SOCKS4 is likely break
some users setup and needs to be taken with more care.
The default values of [proxyDNS] now defaults to true for SOCKS5 proxies.
When creating nsIProxyInfo objects of SOCKS4 proxies, the default value
false is kept. Setting proxyDNS affects both SOCKS4 and SOCKS5 proxy by
modifying both `socks_remote_dns` and `socks5_remote_dns`. Therefore no
extension breakage is expected.
The enterprise policy can also modify the new pref
`network.proxy.socks5_remote_dns`.
Follow up bugs filed while implementing:
* Bug 1890542 - Also disable Prefetch non-manual configurations of socks
proxy
* Bug 1890554 - Use `ProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST` flag in
`nsHttpChannel::GetProxyDNSStrategy`
* Bug 1890549 - nsHttpChannel implementation DNS resolve strategy for
proxies incomplete
* Bug 1893670 - Proxy DNS by default for SOCK4 proxies. Defaulting to
SOCKS4a
[Bug 610896 comment 17]: https://bugzilla.mozilla.org/show_bug.cgi?id=610896#c17
[Bug 610896 comment 11]: https://bugzilla.mozilla.org/show_bug.cgi?id=610896#c11
[Telemetry]: https://bugzilla.mozilla.org/show_bug.cgi?id=1741375#c27
[proxyDNS]: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy/settings#proxydns
Differential Revision: https://phabricator.services.mozilla.com/D207532
135 lines
4.1 KiB
JavaScript
135 lines
4.1 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
const PREF_LOGLEVEL = "browser.policies.loglevel";
|
|
|
|
const lazy = {};
|
|
|
|
ChromeUtils.defineLazyGetter(lazy, "log", () => {
|
|
let { ConsoleAPI } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/Console.sys.mjs"
|
|
);
|
|
return new ConsoleAPI({
|
|
prefix: "ProxyPolicies",
|
|
// tip: set maxLogLevel to "debug" and use log.debug() to create detailed
|
|
// messages during development. See LOG_LEVELS in Console.sys.mjs for details.
|
|
maxLogLevel: "error",
|
|
maxLogLevelPref: PREF_LOGLEVEL,
|
|
});
|
|
});
|
|
|
|
// Don't use const here because this is acessed by
|
|
// tests through the BackstagePass object.
|
|
export var PROXY_TYPES_MAP = new Map([
|
|
["none", Ci.nsIProtocolProxyService.PROXYCONFIG_DIRECT],
|
|
["system", Ci.nsIProtocolProxyService.PROXYCONFIG_SYSTEM],
|
|
["manual", Ci.nsIProtocolProxyService.PROXYCONFIG_MANUAL],
|
|
["autoDetect", Ci.nsIProtocolProxyService.PROXYCONFIG_WPAD],
|
|
["autoConfig", Ci.nsIProtocolProxyService.PROXYCONFIG_PAC],
|
|
]);
|
|
|
|
let proxyPreferences = [
|
|
"network.proxy.type",
|
|
"network.proxy.autoconfig_url",
|
|
"network.proxy.socks_remote_dns",
|
|
"network.proxy.socks5_remote_dns",
|
|
"signon.autologin.proxy",
|
|
"network.proxy.socks_version",
|
|
"network.proxy.no_proxies_on",
|
|
"network.proxy.share_proxy_settings",
|
|
"network.proxy.http",
|
|
"network.proxy.http_port",
|
|
"network.proxy.ssl",
|
|
"network.proxy.ssl_port",
|
|
"network.proxy.socks",
|
|
"network.proxy.socks_port",
|
|
];
|
|
|
|
export var ProxyPolicies = {
|
|
configureProxySettings(param, setPref) {
|
|
if (param.Mode) {
|
|
setPref("network.proxy.type", PROXY_TYPES_MAP.get(param.Mode));
|
|
}
|
|
|
|
if (param.AutoConfigURL) {
|
|
setPref("network.proxy.autoconfig_url", param.AutoConfigURL.href);
|
|
}
|
|
|
|
if (param.UseProxyForDNS !== undefined) {
|
|
setPref("network.proxy.socks_remote_dns", param.UseProxyForDNS);
|
|
setPref("network.proxy.socks5_remote_dns", param.UseProxyForDNS);
|
|
}
|
|
|
|
if (param.AutoLogin !== undefined) {
|
|
setPref("signon.autologin.proxy", param.AutoLogin);
|
|
}
|
|
|
|
if (param.SOCKSVersion !== undefined) {
|
|
if (param.SOCKSVersion != 4 && param.SOCKSVersion != 5) {
|
|
lazy.log.error("Invalid SOCKS version");
|
|
} else {
|
|
setPref("network.proxy.socks_version", param.SOCKSVersion);
|
|
}
|
|
}
|
|
|
|
if (param.Passthrough !== undefined) {
|
|
setPref("network.proxy.no_proxies_on", param.Passthrough);
|
|
}
|
|
|
|
if (param.UseHTTPProxyForAllProtocols !== undefined) {
|
|
setPref(
|
|
"network.proxy.share_proxy_settings",
|
|
param.UseHTTPProxyForAllProtocols
|
|
);
|
|
}
|
|
|
|
if (param.FTPProxy) {
|
|
lazy.log.warn("FTPProxy support was removed in bug 1574475");
|
|
}
|
|
|
|
function setProxyHostAndPort(type, address) {
|
|
let url;
|
|
try {
|
|
// Prepend https just so we can use the URL parser
|
|
// instead of parsing manually.
|
|
url = new URL(`https://${address}`);
|
|
} catch (e) {
|
|
lazy.log.error(`Invalid address for ${type} proxy: ${address}`);
|
|
return;
|
|
}
|
|
|
|
setPref(`network.proxy.${type}`, url.hostname);
|
|
if (url.port) {
|
|
setPref(`network.proxy.${type}_port`, Number(url.port));
|
|
}
|
|
}
|
|
|
|
if (param.HTTPProxy) {
|
|
setProxyHostAndPort("http", param.HTTPProxy);
|
|
|
|
// network.proxy.share_proxy_settings is a UI feature, not handled by the
|
|
// network code. That pref only controls if the checkbox is checked, and
|
|
// then we must manually set the other values.
|
|
if (param.UseHTTPProxyForAllProtocols) {
|
|
param.SSLProxy = param.SOCKSProxy = param.HTTPProxy;
|
|
}
|
|
}
|
|
|
|
if (param.SSLProxy) {
|
|
setProxyHostAndPort("ssl", param.SSLProxy);
|
|
}
|
|
|
|
if (param.SOCKSProxy) {
|
|
setProxyHostAndPort("socks", param.SOCKSProxy);
|
|
}
|
|
|
|
// All preferences should be locked regardless of whether or not a
|
|
// specific value was set.
|
|
if (param.Locked) {
|
|
for (let preference of proxyPreferences) {
|
|
Services.prefs.lockPref(preference);
|
|
}
|
|
}
|
|
},
|
|
};
|