commit dafc44013c95e87dfd96e7e3fd41c49738db3cb2 Author: Patrick Sun Date: Tue Dec 1 01:56:48 2020 +1100 version 1.2.4 working version for Biukop Secure Internet diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/background.js b/background.js new file mode 100644 index 0000000..fd08f46 --- /dev/null +++ b/background.js @@ -0,0 +1,178 @@ +const DEBUG = 0; +const DIRECT_PROXY = { + type: 'direct' +}; +const DEFAULT_PROXY_SETTINGS = { + type: 'direct', + host: '', + port: 0, + username: '', + password: '', + proxyDNS: false +}; +let proxies = [ DIRECT_PROXY, DIRECT_PROXY ]; +var skipLocal = 1; +var pendingRequests = []; +var currentProxy = 0; + +function buttonClicked() { + currentProxy = (currentProxy ? 0 : 1); + if ( proxies[1].type == 'direct' ){ + currentProxy = 0; + } + browser.storage.local.set({ currentProxy: currentProxy }); + updateState(); +} + +function updateState() { + if(currentProxy==0) + { + browser.browserAction.setIcon({path: "icons/unlock48.png"}); + browser.browserAction.setTitle({title: "Local IP"}); + } + else + { + browser.browserAction.setIcon({path: "icons/lock48.png"}); + browser.browserAction.setTitle({title: "Biukop Secure Internet"}); + } +} + +function decodepass(pass) { + var result = atob(pass); + if (result.length <=3) + return pass; + if ("#!" != result.substring(result.length-3,result.length-1)) + return pass; + var tail = Number(result.substring(2,3)); + result = result.substring(5, result.length - tail); + return result; +} + +function settingsChanged(settings) { + if ("proxySettings" in settings){ + proxies[1] = settings.proxySettings.newValue; + proxies[1].password = decodepass(proxies[1].password); + } + + if ("skipLocal" in settings){ + skipLocal = settings.skipLocal.newValue; + } + + if ("currentProxy" in settings) { + currentProxy = settings.currentProxy.newValue; + updateState(); + } +} + +function completed(requestDetails) { + if (DEBUG) { + console.log("completed request: " + requestDetails.requestId); + } + var index = pendingRequests.indexOf(requestDetails.requestId); + if (index > -1) { + pendingRequests.splice(index, 1); + } + + console.log("completed"); +} + +function provideCredentialsSync(requestDetails) { + console.log("check credential"); + if (!requestDetails.isProxy) + return; + if (!currentProxy == 1) + return; + if (pendingRequests.indexOf(requestDetails.requestId) != -1) { + //if we've seen the request before, assume bad credentials and give up + console.log("Bad proxy credentials for request: " + requestDetails.requestId); + return {cancel:true}; + } + + var credentials = { + username: proxies[1].username, + password: proxies[1].password + } + pendingRequests.push(requestDetails.requestId); + if (DEBUG) { + console.log(`Providing proxy credentials for request: ${requestDetails.requestId} username: ${credentials.username}`); + } + return {authCredentials: credentials}; +} + +function isLocalIPv4(host) +{ + var octets = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/.exec(host); + if(!octets) + return false; + if(octets[1]>255||octets[2]>255||octets[3]>255||octets[4]>255) + return false; + if(octets[1]==10||octets[1]==127) //class A or local loopback + return true; + if(octets[1]==172&&octets[2]>=16&&octets[2]<=31) //class B + return true; + if(octets[1]==192&&octets[2]==168) //class C + return true; + return false; +} + +function isLocal(host) +{ + if(host.indexOf('biukop') != -1) + return true; + + if(host.indexOf('.') == -1) + return true; + if(host.endsWith(".local")) + return true; + if(host=="::1") + return true; + return(isLocalIPv4(host)); +} + +function handleProxyRequest(requestInfo) { + const url = new URL(requestInfo.url); + var host = url.hostname; + var proxyNum = currentProxy; + if (skipLocal) { + if(isLocal(host)) { + if (DEBUG) + console.log(`Local host detected: ${host}`); + proxyNum = 0; + } + } + if (DEBUG) { + console.log(`Proxying: ${url.hostname}`); + console.log(proxies[proxyNum]); + } + return(proxies[proxyNum]); +} + +browser.storage.local.get({ currentProxy: 0, skipLocal: true, proxySettings: DEFAULT_PROXY_SETTINGS }, items=>{ + currentProxy = items.currentProxy; + skipLocal = items.skipLocal; + proxies[1] = items.proxySettings; + proxies[1].password = decodepass(proxies[1].password); + updateState(); +}); + +browser.storage.onChanged.addListener(settingsChanged); +browser.browserAction.onClicked.addListener(buttonClicked); +browser.proxy.onRequest.addListener(handleProxyRequest, {urls: [""]}); +browser.proxy.onError.addListener(error => { + console.error(`Proxy error: ${error.message}`); +}); +browser.webRequest.onAuthRequired.addListener( + provideCredentialsSync, + {urls: [""]}, + ["blocking"] +); +browser.webRequest.onCompleted.addListener( + completed, + {urls: [""]} +); +browser.webRequest.onErrorOccurred.addListener( + completed, + {urls: [""]} +); + + diff --git a/icons/lock48.png b/icons/lock48.png new file mode 100644 index 0000000..cb77238 Binary files /dev/null and b/icons/lock48.png differ diff --git a/icons/lock96.png b/icons/lock96.png new file mode 100644 index 0000000..3ef70c6 Binary files /dev/null and b/icons/lock96.png differ diff --git a/icons/unlock48.png b/icons/unlock48.png new file mode 100644 index 0000000..36d1997 Binary files /dev/null and b/icons/unlock48.png differ diff --git a/icons/unlock96.png b/icons/unlock96.png new file mode 100644 index 0000000..f6535df Binary files /dev/null and b/icons/unlock96.png differ diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..2f99238 --- /dev/null +++ b/manifest.json @@ -0,0 +1,44 @@ +{ + "manifest_version": 2, + "name": "Biukop Secure Internet", + "version": "1.2.4", + "description": "Enforced Security communication through professional network.", + "icons": { + "48": "icons/lock48.png", + "96": "icons/lock96.png" + }, + "permissions": [ + "storage", + "proxy", + "", + "webRequest", + "webRequestBlocking" + ], + "browser_action": { + "browser_style": true, + "default_icon": "icons/lock48.png", + "default_title": "Secure Channel - Biukop" + }, + "commands": { + "_execute_browser_action": { + "suggested_key": { + "default": "Ctrl+Shift+Y" + }, + "description": "Enable/Disable Secure Connection" + } + }, + "background": { + "scripts": [ + "background.js" + ] + }, + "options_ui": { + "page": "settings.html", + "browser_style": true + }, + "applications": { + "gecko": { + "strict_min_version": "68.0" + } + } +} \ No newline at end of file diff --git a/settings.css b/settings.css new file mode 100644 index 0000000..d2fa93b --- /dev/null +++ b/settings.css @@ -0,0 +1,37 @@ +#dnsrow{ + display: none; +} +.configtable { + border-collapse:collapse; + margin: 0px; + font-size: 12pt; + width:100%; + border: 0px dotted grey; + box-shadow: 3px 3px 12px #000 inset; + border-radius: 10px; +} +.configtable th,.configtable td { + border: 1px solid white; + padding: 10px; +} +.configtable th { + color: #000; + font-size: 18px; + text-align: left; +} + +.configtable td { + width: 50%; +} + +.configtable tr { + background-color: lavender; + transition: background-color 0.5s ease; +} +.configtable tr:hover { + background-color: #fff; +} + +td.authcode { + width:90%; +} \ No newline at end of file diff --git a/settings.html b/settings.html new file mode 100644 index 0000000..33ce94e --- /dev/null +++ b/settings.html @@ -0,0 +1,75 @@ + + + + + + + + +
+ + + + + + + + + + + + + +
+ License Code: +
+ + + +
+
abcd
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ Authorized Settings +
Type + +
Host
Port
Username
Enabled
+
+ + + \ No newline at end of file diff --git a/settings.js b/settings.js new file mode 100644 index 0000000..6d588dd --- /dev/null +++ b/settings.js @@ -0,0 +1,200 @@ +var g_mid = ""; + +function saveCurrentProxy(e) { + e.preventDefault(); + browser.storage.local.set({ + currentProxy: document.querySelector("#currentProxy").checked?1:0 + }); +} + +function showproxy(config){ + document.querySelector("#host").value = config.host ; + document.querySelector("#port").value = config.port ; + document.querySelector('#type [value="socks"]').selected = true; + document.querySelector("#username").value = config.username; + + if (config.host == ""){ + document.querySelector("#currentProxy").checked = false; + document.querySelector("#currentProxy").disabled = true; + }else{ + document.querySelector("#currentProxy").checked = config.enable; + document.querySelector("#currentProxy").disabled = false; + } + updateState(); +} + +function updateState() { + if(currentProxy==0) + { + browser.browserAction.setIcon({path: "icons/unlock48.png"}); + browser.browserAction.setTitle({title: "Local IP"}); + } + else + { + browser.browserAction.setIcon({path: "icons/lock48.png"}); + browser.browserAction.setTitle({title: "Biukop Secure Internet"}); + } +} + +function IsJsonString(str) { + try { + JSON.parse(str); + } catch (e) { + return false; + } + return true; +} + +function showMessage(msg) { + var el = document.querySelector("#errMsg"); + if (msg != undefined) + el.innerText = msg; + else{ + el.innerText = ""; + } +} + +function showLink(href, text) { + console.log(href); + console.log(text); + var el = document.querySelector("#msgLink"); + if ( href != undefined && text !=undefined ) { + el.href = href; + el.innerText = text; + el.visibility = 'visible'; + }else{ + el.innerText = ''; + el.visibility = 'hidden'; + } +} + +function defaultConfig(){ + return { + type: 'direct', + host: '', + port: 0, + username: '', + password: '', + proxyDNS: false, + enable:false, + } +} + +function isValidResponse(msg){ + if ( IsJsonString(xhr.responseText) ){ + config = JSON.parse(xhr.responseText); + config.success = true; + } + return false; +} + +function license(val){ + + if ( val == undefined || val == "" || val.length < 5 ){ + showMessage("Please enter a valid license"); + return; + } + + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function() { + if (xhr.readyState === 4){ + var config = defaultConfig(); + if (IsJsonString(xhr.responseText)) { + config = JSON.parse(xhr.responseText); + showMessage(config.errMsg); + showLink(config.link, config.linkText); + }else{ + showMessage(xhr.responseText); + showLink('',''); + } + showproxy(config); + + browser.storage.local.set({ + proxySettings: { + type: config.type, + host: config.host, + port: config.port, + username: config.username, + password: config.password, + proxyDNS: config.proxyDNS, + }, + skipLocal: true, + mid: g_mid, + license: val, + currentProxy: config.enable? 1: 0 + }); + } + }; + xhr.open('POST', 'https://license.biukop.com.au/dedicatedip/'); + //xhr.open('POST', 'https://lawipac.com/dumprequest.php'); + xhr.setRequestHeader('Content-Type', 'application/json'); + var data = { + license: val, + mid: g_mid + }; + xhr.send(JSON.stringify(data)); + +} + + + +function restoreOptions(e) { + + function onGot(item) { + g_mid = item.mid; + init_mid(item.mid); //just in case + document.querySelector("#license").value = item.license; + document.querySelector("#currentProxy").checked = item.currentProxy ==1; + license(item.license); + } + + function onError(error) { + console.log(`Error: ${error}`); + } + var gettingItem = browser.storage.local.get({ + mid: "", + currentProxy: 0, + skipLocal: true, + license: "", + proxySettings: { + type: 'direct', + host: '', + port: 0, + username: '', + password: '', + proxyDNS: false + } + }); + gettingItem.then(onGot, onError); + + +} + + +function register(e) { + e.preventDefault(); + var license_code = document.querySelector("#license").value; + license(license_code); +} + + +document.addEventListener("DOMContentLoaded", restoreOptions); +document.querySelector("#currentProxy").addEventListener("change", saveCurrentProxy); +document.querySelector("#register").addEventListener("click", register); + +function init_mid(existing_id) { + function createUUID() { + var uuid = new Date().valueOf(); + return (uuid + '-xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx').replace(/[xy]/g, function(c) { + var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + } + + if ( existing_id== undefined || existing_id == "" || existing_id.length < 10 ){ + var uuid = createUUID(); + console.log("create new mid =:" + uuid) ; + g_mid = uuid; + browser.storage.local.set({mid: uuid}); + } +}