From 06e7ad67f0632ed6c3ee44db3c409edbe069bf8c Mon Sep 17 00:00:00 2001 From: FelisCatus Date: Wed, 20 Sep 2017 13:34:54 -0700 Subject: [PATCH] Use object return types when possible on Firefox with auth. Fix #1172. --- omega-pac/src/profiles.coffee | 16 ++++++-- .../src/js/omega_webext_proxy_script.js | 35 ++++++++++++---- .../src/module/options.coffee | 41 +++++++++++++++---- .../omega/controllers/fixed_profile.coffee | 7 +++- 4 files changed, 77 insertions(+), 22 deletions(-) diff --git a/omega-pac/src/profiles.coffee b/omega-pac/src/profiles.coffee index 951c69a..c28cc70 100644 --- a/omega-pac/src/profiles.coffee +++ b/omega-pac/src/profiles.coffee @@ -257,10 +257,20 @@ module.exports = exports = if profile.bypassList for cond in profile.bypassList if Conditions.match(cond, request) - return [@pacResult(), cond] + return [@pacResult(), cond, {scheme: 'direct'}, null] for s in @schemes when s.scheme == request.scheme and profile[s.prop] - return [@pacResult(profile[s.prop]), s.scheme] - return [@pacResult(profile.fallbackProxy), ''] + return [ + @pacResult(profile[s.prop]), + s.scheme, + profile[s.prop], + profile.auth?[s.prop] ? profile.auth?['all'] + ] + return [ + @pacResult(profile.fallbackProxy), + '', + profile.fallbackProxy, + profile.auth?.fallbackProxy ? profile.auth?['all'] + ] compile: (profile) -> if ((not profile.bypassList or not profile.fallbackProxy) and not profile.proxyForHttp and not profile.proxyForHttps and diff --git a/omega-target-chromium-extension/src/js/omega_webext_proxy_script.js b/omega-target-chromium-extension/src/js/omega_webext_proxy_script.js index ea975c0..0a653c7 100644 --- a/omega-target-chromium-extension/src/js/omega_webext_proxy_script.js +++ b/omega-target-chromium-extension/src/js/omega_webext_proxy_script.js @@ -35,18 +35,35 @@ FindProxyForURL = (function () { if (Array.isArray(matchResult)) { next = matchResult[0]; - // TODO: Maybe also return user/pass if Mozilla supports it or it ends - // up standardized in WebExtensions in the future. - // MOZ: Mozilla has a bug tracked for user/pass in PAC return value. - // https://bugzilla.mozilla.org/show_bug.cgi?id=1319641 - if (next.charCodeAt(0) !== 43) { + var proxy = matchResult[2]; + var auth = matchResult[3]; + if (proxy && !state.useLegacyStringReturn) { + var proxyInfo = { + type: proxy.scheme, + host: proxy.host, + port: proxy.port, + }; + if (proxyInfo.type === 'socks5') { + // MOZ: SOCKS5 proxies are identified by "type": "socks". + // https://dxr.mozilla.org/mozilla-central/rev/ffe6cc09ccf38cca6f0e727837bbc6cb722d1e71/toolkit/components/extensions/ProxyScriptContext.jsm#51 + proxyInfo.type = 'socks'; + // Enable SOCKS5 remote DNS. + // TODO(catus): Maybe allow the users to configure this? + proxyInfo.proxyDNS = true; + } + if (auth) { + proxyInfo.username = auth.username; + proxyInfo.password = auth.password; + } + return [proxyInfo]; + } else if (next.charCodeAt(0) !== 43) { + // MOZ: Legacy proxy support expects PAC-like string return type. + // TODO(catus): Remove support for string return type. // MOZ: SOCKS5 proxies are supported under the prefix SOCKS. - // https://dxr.mozilla.org/mozilla-central/source/toolkit/components/extensions/ProxyScriptContext.jsm#178 + // https://dxr.mozilla.org/mozilla-central/rev/ffe6cc09ccf38cca6f0e727837bbc6cb722d1e71/toolkit/components/extensions/ProxyScriptContext.jsm#51 // Note: We have to replace this because MOZ won't process the rest of // the list if the syntax of the first item is not recognized. - next = next.replace(/SOCKS5 /g, 'SOCKS '); - - return next; + return next.replace(/SOCKS5 /g, 'SOCKS '); } } else if (matchResult.profileName) { next = OmegaPac.Profiles.nameAsKey(matchResult.profileName) diff --git a/omega-target-chromium-extension/src/module/options.coffee b/omega-target-chromium-extension/src/module/options.coffee index e9103fc..fb59c46 100644 --- a/omega-target-chromium-extension/src/module/options.coffee +++ b/omega-target-chromium-extension/src/module/options.coffee @@ -199,10 +199,22 @@ class ChromeOptions extends OmegaTarget.Options @_proxyScriptDisabled = true else @_proxyScriptState = state - @_initWebextProxyScript().then => @_proxyScriptStateChanged() - # Proxy authentication is not covered in WebExtensions standard now. - # MOZ: Mozilla has a bug tracked to implemented it in PAC return value. - # https://bugzilla.mozilla.org/show_bug.cgi?id=1319641 + Promise.all([ + browser.runtime.getBrowserInfo(), + @_initWebextProxyScript(), + ]).then ([info]) => + if info.vendor == 'Mozilla' and info.buildID < '20170918220054' + # MOZ: Legacy proxy support expects PAC-like string return type. + # TODO(catus): Remove support for string return type. + @log.error( + 'WARNING: Your browser is outdated! SOCKS5 DNS/Auth unsupported!') + @log.error('Please update your browser ASAP!') + @log.error("useLegacyStringReturn=true for Build: #{info.buildID}.") + @_proxyScriptState.useLegacyStringReturn = true + @_proxyScriptStateChanged() + @_proxyAuth ?= new ProxyAuth(this) + @_proxyAuth.listen() + @_proxyAuth.setProxies(@_watchingProfiles) return Promise.resolve() _proxyScriptInitialized: false @@ -210,11 +222,22 @@ class ChromeOptions extends OmegaTarget.Options _initWebextProxyScript: -> if not @_proxyScriptInitialized browser.proxy.onProxyError.addListener (err) => - if err and err.message.indexOf('Invalid Proxy Rule: DIRECT') >= 0 - # DIRECT cannot be parsed in Mozilla earlier due to a bug. Even though - # it throws, it actually falls back to direct connection so it works. - # https://bugzilla.mozilla.org/show_bug.cgi?id=1355198 - return + if err?.message? + if err.message.indexOf('Invalid Proxy Rule: DIRECT') >= 0 + # DIRECT cannot be parsed in Mozilla earlier due to a bug. Even + # though it throws, it actually falls back to direct connection + # so it works. + # https://bugzilla.mozilla.org/show_bug.cgi?id=1355198 + return + if err.message.indexOf('Return type must be a string') >= 0 + # MOZ: Legacy proxy support expects PAC-like string return type. + # TODO(catus): Remove support for string return type. + @log.error( + 'WARNING: Your browser is outdated! Remote DNS is unsupported!') + @log.error('Please update your browser ASAP!') + @_proxyScriptState.useLegacyStringReturn = true + @_proxyScriptStateChanged() + return @log.error(err) browser.runtime.onMessage.addListener (message) => return unless message.event == 'proxyScriptLog' diff --git a/omega-web/src/omega/controllers/fixed_profile.coffee b/omega-web/src/omega/controllers/fixed_profile.coffee index 74cd8cf..9476ac5 100644 --- a/omega-web/src/omega/controllers/fixed_profile.coffee +++ b/omega-web/src/omega/controllers/fixed_profile.coffee @@ -38,7 +38,12 @@ angular.module('omega').controller 'FixedProfileCtrl', ($scope, $modal, $scope.proxyEditors = {} - $scope.authSupported = {"http": true, "https": true} + socks5AuthSupported = (browser?.proxy?.register?) + $scope.authSupported = { + "http": true, + "https": true, + "socks5": socks5AuthSupported, + } $scope.isProxyAuthActive = (scheme) -> return $scope.profile.auth?[proxyProperties[scheme]]? $scope.editProxyAuth = (scheme) ->