From 43e0a54064df95e76c3a9f3ddacdf6486bbecc42 Mon Sep 17 00:00:00 2001 From: lunu Bounir Date: Sun, 17 Jan 2021 07:17:25 +0100 Subject: [PATCH] updating tor --- extension/background.js | 142 ++++++++++++++++++++---------- extension/data/installer/index.js | 33 ++++--- extension/data/options/index.html | 55 ++++++++++++ extension/data/options/index.js | 49 +++++++++++ extension/manifest.json | 14 ++- extension/proxy.js | 4 + extension/tor.js | 6 +- helper/os/win/install.bat | 33 +++---- helper/package.sh | 6 +- misc/icon.xcf | Bin 0 -> 54532 bytes 10 files changed, 257 insertions(+), 85 deletions(-) create mode 100644 extension/data/options/index.html create mode 100644 extension/data/options/index.js create mode 100644 extension/proxy.js create mode 100644 misc/icon.xcf diff --git a/extension/background.js b/extension/background.js index 083362b..c015542 100644 --- a/extension/background.js +++ b/extension/background.js @@ -1,12 +1,13 @@ -/* globals Tor, Events */ +/* globals Tor, Events, browser */ 'use strict'; var prefs = { ports: [2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030], - threads: 2, + threads: 1, badge: true, start: false, - native: false + native: false, + arguments: '' }; chrome.storage.local.get(prefs, ps => { Object.assign(prefs, ps); @@ -20,13 +21,8 @@ chrome.storage.local.get(prefs, ps => { app.connect(); } if (!r) { - chrome.windows.create({ - url: chrome.extension.getURL('data/installer/index.html'), - width: 600, - height: 450, - left: screen.availLeft + Math.round((screen.availWidth - 600) / 2), - top: screen.availTop + Math.round((screen.availHeight - 450) / 2), - type: 'popup' + chrome.storage.local.set({ + native: false }); } }); @@ -47,28 +43,41 @@ chrome.storage.onChanged.addListener(ps => { var proxy = {}; proxy.update = () => { if (app.connected.length || app.mode === 'connected') { - const config = { - mode: 'pac_script', - pacScript: { - data: `function FindProxyForURL() { - const ports = ${JSON.stringify(app.connected)}; - if (ports.length) { - const port = ports[Math.floor(Math.random() * ports.length)]; - return 'SOCKS localhost:' + port; + const data = `function FindProxyForURL() { + const ports = ${JSON.stringify(app.connected)}; + if (ports.length) { + const port = ports[Math.floor(Math.random() * ports.length)]; + return 'SOCKS localhost:' + port; + } + else { + return 'SOCKS localhost:2020'; + } + }`; + if (/Firefox/.test(navigator.userAgent)) { + browser.proxy.settings.clear({}, () => { + browser.proxy.settings.set({ + value: { + proxyType: 'autoConfig', + autoConfigUrl: 'data:text/javascript,' + encodeURIComponent(data), + proxyDNS: true } - else { - return 'SOCKS localhost:2020'; + }); + }); + } + else { + chrome.proxy.settings.clear({ + scope: 'regular' + }, () => chrome.proxy.settings.set({ + value: { + mode: 'pac_script', + pacScript: { + data, + mandatory: true } - }`, - mandatory: true - } - }; - chrome.proxy.settings.clear({ - scope: 'regular' - }, () => chrome.proxy.settings.set({ - value: config, - scope: 'regular' - })); + }, + scope: 'regular' + })); + } } else { chrome.proxy.settings.clear({ @@ -113,27 +122,42 @@ tor.on('disconnected', ids => { app.connect = port => { if (prefs.native === false) { app.notify('Native Client is not found. Follow the instruction to install it'); + chrome.windows.create({ + url: chrome.extension.getURL('data/installer/index.html'), + width: 600, + height: 450, + left: screen.availLeft + Math.round((screen.availWidth - 600) / 2), + top: screen.availTop + Math.round((screen.availHeight - 450) / 2), + type: 'popup' + }); return; } - app.mode = 'connected'; - if (app.ids.length === 0) { - app.emit('connecting'); - } - if (port) { - app.ids.push(port); - tor.connect(port); - } - else { - for (const port of prefs.ports.slice(0, prefs.threads)) { + chrome.proxy.settings.get({}, e => { + if (e.levelOfControl === 'controllable_by_this_extension' || e.levelOfControl === 'controlled_by_this_extension') { + app.mode = 'connected'; + if (app.ids.length === 0) { + app.emit('connecting'); + } if (port) { app.ids.push(port); - tor.connect(port); + tor.connect(port, prefs.arguments); } else { - console.error('no more ports to use'); + for (const port of prefs.ports.slice(0, prefs.threads)) { + if (port) { + app.ids.push(port); + tor.connect(port, prefs.arguments); + } + else { + console.error('no more ports to use'); + } + } } } - } + else { + app.notify('Cannot control your browser\'s proxy settings; ' + e.levelOfControl); + } + }); }; app.disconnect = (trusted = false) => { @@ -155,7 +179,7 @@ app.fix = () => { const n = prefs.threads - len; const ports = prefs.ports.filter(p => app.ids.indexOf(p) === -1); ports.slice(0, n).forEach(port => app.connect(port)); - app.notify('Increasing # of channels by ' + n); + app.notify('Increasing # of channels by ' + n + '. Please wait...'); } }; @@ -194,7 +218,6 @@ app.notify = message => chrome.notifications.create({ var timer; app.on('connecting', () => { - console.log('connecting'); app.title(`Connecting to the Tor network (${prefs.threads} channels)`); app.icon('connecting'); window.clearInterval(timer); @@ -202,18 +225,15 @@ app.on('connecting', () => { proxy.update(); }); app.on('connected', () => { - console.log('connected'); window.clearInterval(timer); app.icon('connected'); }); app.on('update', () => { - console.log('update'); app.title(`Connected to the Tor network (${app.connected.length} channels)`); app.badge(app.connected.length ? String(app.connected.length) : ''); proxy.update(); }); app.on('disconnected', () => { - console.log('disconnected'); window.clearInterval(timer); app.title('Disconnected from the Tor network'); app.icon(app.mode === 'disconnected' ? 'disconnected' : 'unexpected'); @@ -236,3 +256,29 @@ chrome.browserAction.onClicked.addListener(() => { chrome.browserAction.setBadgeBackgroundColor({ color: '#7d4798' }); + +{ + const {onInstalled, setUninstallURL, getManifest} = chrome.runtime; + const {name, version} = getManifest(); + const page = getManifest().homepage_url; + onInstalled.addListener(({reason, previousVersion}) => { + chrome.storage.local.get({ + 'faqs': true, + 'last-update': 0 + }, prefs => { + if (reason === 'install' || (prefs.faqs && reason === 'update')) { + const doUpdate = (Date.now() - prefs['last-update']) / 1000 / 60 / 60 / 24 > 45; + if (doUpdate && previousVersion !== version) { + chrome.tabs.create({ + url: page + '?version=' + version + + (previousVersion ? '&p=' + previousVersion : '') + + '&type=' + reason, + active: reason === 'install' + }); + chrome.storage.local.set({'last-update': Date.now()}); + } + } + }); + }); + setUninstallURL(page + '?rd=feedback&name=' + encodeURIComponent(name) + '&version=' + version); +} diff --git a/extension/data/installer/index.js b/extension/data/installer/index.js index 096cce1..2beab6b 100644 --- a/extension/data/installer/index.js +++ b/extension/data/installer/index.js @@ -1,40 +1,39 @@ -var name; +var filename; var os; (() => { if (navigator.platform.startsWith('Mac')) { os = 'mac'; - name = 'mac.zip'; + filename = 'mac.zip'; } else if (navigator.platform.startsWith('Win')) { os = 'windows'; if (navigator.userAgent.indexOf('WOW64') != -1 || navigator.userAgent.indexOf('Win64') != -1) { - name = 'win_64.zip'; + filename = 'win_64.zip'; } else { - name = 'win_32.zip'; + filename = 'win_32.zip'; } } else { os = 'linux'; - name = 'linux_64.zip'; + filename = 'linux_64.zip'; } })(); -const url = 'https://github.com/lunu-bounir/onion-helper/releases/download/0.1.0/' + name; +document.body.dataset.os = os; +const url = 'https://github.com/lunu-bounir/onion-vpn/releases/download/0.1.0/' + filename; if (navigator.platform.startsWith('Mac') || navigator.platform.startsWith('Win')) { - document.getElementById('package').href = url; - document.getElementById('package').download = name; + document.getElementById('package').dataset.href = url; document.getElementById('uninstall').textContent = 'uninstall.' + (os === 'windows' ? 'bat' : 'sh'); } else { alert('Your operating system is not yet supported'); } -fetch('https://api.github.com/repos/lunu-bounir/onion-helper/releases/latest').then(r => r.json()).then(obj => { - const link = obj.assets.filter(a => a.name === name)[0].browser_download_url; - console.log(link); - document.getElementById('package').href = link; +fetch('https://api.github.com/repos/lunu-bounir/onion-vpn/releases/latest').then(r => r.json()).then(obj => { + const link = obj.assets.filter(a => a.name === filename)[0].browser_download_url; + document.getElementById('package').dataset.href = link; }).catch(e => alert(e.message)); chrome.runtime.sendNativeMessage('onion.vpn.helper', { @@ -48,3 +47,13 @@ chrome.runtime.sendNativeMessage('onion.vpn.helper', { document.getElementById('restart').addEventListener('click', () => { chrome.runtime.reload(); }); + +document.getElementById('package').addEventListener('click', e => { + chrome.downloads.download({ + url: e.target.dataset.href, + filename + }); + e.preventDefault(); + e.target.parentElement.style['text-decoration'] = 'line-through'; + chrome.runtime.getBackgroundPage(b => b.app.notify('Please wait for the download to finish')); +}); diff --git a/extension/data/options/index.html b/extension/data/options/index.html new file mode 100644 index 0000000..b8dde8f --- /dev/null +++ b/extension/data/options/index.html @@ -0,0 +1,55 @@ + + + + Onion VPN :: Options Page + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Comma-separated list of ports1
Additional command-line arguments3
+

+ + - +

+
+ 1: When starting a new Tor instance, use a port number among this list. +
+ 2: Note that you will be disconnected until the extension successfully establishes its first connection +
+ 3: Comma-separated list of additional arguments to pass to the Tor executable. It is user responsibility to make sure these additional arguments are not going to conflict with the extension operation. For instance for the Tor client to make all OR connections through the SOCKS 5 proxy, use Socks5Proxy, 127.0.0.1:9191 + + + + diff --git a/extension/data/options/index.js b/extension/data/options/index.js new file mode 100644 index 0000000..734c6fb --- /dev/null +++ b/extension/data/options/index.js @@ -0,0 +1,49 @@ +'use strict'; + +var info = document.getElementById('info'); + +chrome.storage.local.get({ + ports: [2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030], + badge: true, + start: false, + arguments: '' +}, prefs => { + document.getElementById('ports').value = prefs.ports.join(', '); + document.getElementById('badge').checked = prefs.badge; + document.getElementById('start').checked = prefs.start; + document.getElementById('arguments').value = prefs.arguments; +}); + +document.getElementById('save').addEventListener('click', () => { + let ports = document.getElementById('ports').value.split(/\s*,\s*/).filter(s => s && isNaN(s) === false); + ports = ports.length ? ports : [2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030]; + chrome.storage.local.set({ + ports, + badge: document.getElementById('badge').checked, + start: document.getElementById('start').checked, + arguments: document.getElementById('arguments').value + }, () => { + document.getElementById('ports').value = ports.join(', '); + info.textContent = 'Options saved'; + window.setTimeout(() => info.textContent = '', 750); + }); +}); + +// reset +document.getElementById('reset').addEventListener('click', e => { + if (e.detail === 1) { + info.textContent = 'Double-click to reset!'; + window.setTimeout(() => info.textContent = '', 750); + } + else { + localStorage.clear(); + chrome.storage.local.clear(() => { + chrome.runtime.reload(); + window.close(); + }); + } +}); +// support +document.getElementById('support').addEventListener('click', () => chrome.tabs.create({ + url: chrome.runtime.getManifest().homepage_url + '?rd=donate' +})); diff --git a/extension/manifest.json b/extension/manifest.json index a01e9a5..8a382e4 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -1,15 +1,17 @@ { "manifest_version" :2, - "version": "0.1.0", - "name": "Onion VPN with load balancing", - "description": "Simultaneously connect to multiple Tor proxy servers to increase anonymity and speed", + "version": "0.1.2", + "name": "Onion VPN with Speed Control", + "description": "Simultaneously connect to multiple Tor proxy servers using load balancing to increase anonymity and speed", "permissions": [ "proxy", "nativeMessaging", "contextMenus", "storage", - "notifications" + "notifications", + "downloads" ], + "homepage_url": "https://add0n.com/onion-network.html", "background": { "scripts": [ "tor.js", @@ -36,5 +38,9 @@ "64": "data/icons/disconnected/64.png", "128": "data/icons/disconnected/128.png" } + }, + "options_ui": { + "page": "data/options/index.html", + "chrome_style": true } } diff --git a/extension/proxy.js b/extension/proxy.js new file mode 100644 index 0000000..2f2691a --- /dev/null +++ b/extension/proxy.js @@ -0,0 +1,4 @@ + +function FindProxyForURL(url) { + return 'SOCKS 192.168.2.147:9696'; +} diff --git a/extension/tor.js b/extension/tor.js index bcae3b3..ef75ba4 100644 --- a/extension/tor.js +++ b/extension/tor.js @@ -25,7 +25,7 @@ class Tor extends Events { killall: 'killall tor' }; } - connect(socksPort) { + connect(socksPort, args = '') { if (Object.keys(this.instances).length === 0) { this.port = chrome.runtime.connectNative('onion.vpn.helper'); this.port.onMessage.addListener(r => { @@ -55,6 +55,7 @@ class Tor extends Events { stdout: '', stderr: '' }; + this.port.postMessage({ method: 'spawn', id: socksPort, @@ -64,7 +65,8 @@ class Tor extends Events { 'SocksPort', String(socksPort), 'GeoIPFile', 'geoip', 'GeoIPv6File', 'geoip6', - 'DataDirectory', String(socksPort) + 'DataDirectory', String(socksPort), + ...args.split(/\s*,\s*/).filter(s => s) ] }); } diff --git a/helper/os/win/install.bat b/helper/os/win/install.bat index b31f7ef..87936af 100644 --- a/helper/os/win/install.bat +++ b/helper/os/win/install.bat @@ -3,25 +3,27 @@ pushd "%~dp0" SET ID=onion.vpn.helper -SET =native part of the Onion VPN extension +SET DESCRIPTION=native part of the Onion VPN extension SET PATH=C:\Windows\System32;%PATH% +FOR %%f in ("%LocalAPPData%") do SET SHORT_PATH=%%~sf + ECHO .. Kill already running instances taskkill /im tor.exe /f >nul 2>&1 taskkill /im node.exe /f >nul 2>&1 ECHO. -ECHO .. Copy %FILE% to %LocalAPPData%\%ID%\ -mkdir %LocalAPPData%\%ID% -mkdir %LocalAPPData%\%ID%\node -copy assets\node\* %LocalAPPData%\%ID%\node\ -mkdir %LocalAPPData%\%ID%\tor -copy assets\tor\* %LocalAPPData%\%ID%\tor\ -copy assets\app.js %LocalAPPData%\%ID%\ -copy assets\messaging.js %LocalAPPData%\%ID%\ - -ECHO .. Copy Firefox manifest to %LocalAPPData%\%ID%\manifest-firefox.json +ECHO .. Copy %FILE% to %SHORT_PATH%\%ID%\ +mkdir %SHORT_PATH%\%ID% +mkdir %SHORT_PATH%\%ID%\node +copy assets\node\* %SHORT_PATH%\%ID%\node\ +mkdir %SHORT_PATH%\%ID%\tor +copy assets\tor\* %SHORT_PATH%\%ID%\tor\ +copy assets\app.js %SHORT_PATH%\%ID%\ +copy assets\messaging.js %SHORT_PATH%\%ID%\ + +ECHO .. Copy Firefox manifest to %SHORT_PATH%\%ID%\manifest-firefox.json ( ECHO { ECHO "name": "%ID%", @@ -30,8 +32,8 @@ ECHO .. Copy Firefox manifest to %LocalAPPData%\%ID%\manifest-firefox.json ECHO "type": "stdio", ECHO "allowed_extensions": ["{4d0fd54a-4590-45af-a943-60330144f676}"] ECHO } -) > %LocalAPPData%\%ID%\manifest-firefox.json -ECHO .. Copy Chrome manifest to %LocalAPPData%\%ID%\manifest-chrome.json +) > %SHORT_PATH%\%ID%\manifest-firefox.json +ECHO .. Copy Chrome manifest to %SHORT_PATH%\%ID%\manifest-chrome.json ( ECHO { ECHO "name": "%ID%", @@ -40,17 +42,16 @@ ECHO .. Copy Chrome manifest to %LocalAPPData%\%ID%\manifest-chrome.json ECHO "type": "stdio", ECHO "allowed_origins": ["chrome-extension://diekiockdlleigoinkcjjkpnpapbkfbo/", "chrome-extension://laodgoeoeloaponlioalomjadbmkkkhd/"] ECHO } -) > %LocalAPPData%\%ID%\manifest-chrome.json +) > %SHORT_PATH%\%ID%\manifest-chrome.json ECHO. ECHO .. Writting to Chrome Registry ECHO .. Key: HKCU\Software\Google\Chrome\NativeMessagingHosts\%ID% -REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\%ID%" /ve /t REG_SZ /d "%LocalAPPData%\%ID%\manifest-chrome.json" /f +REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\%ID%" /ve /t REG_SZ /d "%SHORT_PATH%\%ID%\manifest-chrome.json" /f ECHO. ECHO .. Writting to Firefox Registry ECHO .. Key: HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\%ID% -FOR %%f in ("%LocalAPPData%") do SET SHORT_PATH=%%~sf REG ADD "HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\%ID%" /ve /t REG_SZ /d "%SHORT_PATH%\%ID%\manifest-firefox.json" /f echo .. Done! diff --git a/helper/package.sh b/helper/package.sh index c3c64d5..c5b49ca 100755 --- a/helper/package.sh +++ b/helper/package.sh @@ -4,7 +4,7 @@ cd helper # get the official tor executable from www.torproject.org cd os/mac -wget -O TorBrowser.dmg https://www.torproject.org/dist/torbrowser/8.0.5/TorBrowser-8.0.5-osx64_en-US.dmg +wget -O TorBrowser.dmg https://www.torproject.org/dist/torbrowser/10.0.8/TorBrowser-10.0.8-osx64_en-US.dmg dmg2img TorBrowser.dmg TorBrowser.img 7z e TorBrowser.img tor.real -r mv tor.real tor @@ -12,8 +12,8 @@ chmod +x tor cd ../.. cd os/win -wget https://www.torproject.org/dist/torbrowser/8.0.5/tor-win32-0.3.5.7.zip -7z e tor-win32-0.3.5.7.zip tor.exe *.dll -r +wget https://www.torproject.org/dist/torbrowser/10.0.8/tor-win32-0.4.4.6.zip +7z e tor-win32-0.4.4.6.zip tor.exe *.dll -r cd ../.. pwd ls diff --git a/misc/icon.xcf b/misc/icon.xcf new file mode 100644 index 0000000000000000000000000000000000000000..211efb59a667a8927306e43c64d38b83a4cd8cb7 GIT binary patch literal 54532 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ǑpL@Rv{)l}VM`+8ts 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 ZBE&yQf6_lq=wx93B%@eA#0N0_{{fOb!65(u literal 0 HcmV?d00001