First merge with Chrome et Firefox web extension (not tested in chrome)
This commit is contained in:
parent
1d71ca6861
commit
e759c13d64
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2013-2014 Grégory Soutadé
|
Copyright (C) 2013-2016 Grégory Soutadé
|
||||||
|
|
||||||
This file is part of gPass.
|
This file is part of gPass.
|
||||||
|
|
||||||
|
@ -17,12 +17,8 @@
|
||||||
along with gPass. If not, see <http://www.gnu.org/licenses/>.
|
along with gPass. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var DEBUG = false;
|
var DEBUG = true;
|
||||||
var default_preferences = {"pkdbf2_level": 1000,
|
|
||||||
"account_url": "https://gpass-demo.soutade.fr/demo"};
|
|
||||||
var preferences = {};
|
|
||||||
var protocol_version = 3;
|
var protocol_version = 3;
|
||||||
var pkdbf2_level;
|
|
||||||
|
|
||||||
SERVER = {OK : 0, FAILED : 1, RESTART_REQUEST : 2};
|
SERVER = {OK : 0, FAILED : 1, RESTART_REQUEST : 2};
|
||||||
|
|
||||||
|
@ -34,11 +30,11 @@ function hex2a(hex) {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
function a2hex(str) {
|
function a2hex(_str_) {
|
||||||
var hex = '';
|
var hex = '';
|
||||||
for (var i = 0; i < str.length; i++)
|
for (var i = 0; i < _str_.length; i++)
|
||||||
{
|
{
|
||||||
var c = str.charCodeAt(i).toString(16);
|
var c = _str_.charCodeAt(i).toString(16);
|
||||||
if (c.length == 1) c = "0" + c;
|
if (c.length == 1) c = "0" + c;
|
||||||
hex += c;
|
hex += c;
|
||||||
}
|
}
|
||||||
|
@ -51,56 +47,41 @@ function debug(s)
|
||||||
console.log(s);
|
console.log(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
function notify(text, data)
|
|
||||||
{
|
|
||||||
chrome.extension.sendMessage({type: "notification", options:{"message":text}}, function(response){alert(response);});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPref(key)
|
|
||||||
{
|
|
||||||
if (key in preferences)
|
|
||||||
return preferences[key];
|
|
||||||
else
|
|
||||||
return default_preferences[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPref(key, value)
|
|
||||||
{
|
|
||||||
chrome.storage.local.set({key:value}, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
function generate_request(domain, login, mkey)
|
function generate_request(domain, login, mkey)
|
||||||
{
|
{
|
||||||
var v = "@@" + domain + ";" + login;
|
var v = "@@" + domain + ";" + login;
|
||||||
debug("will encrypt " + v);
|
debug("will encrypt " + v);
|
||||||
debug("with " + a2hex(mkey));
|
//debug("with " + a2hex(mkey));
|
||||||
var enc = aes.encryptLongString(v, aes.init(mkey));
|
enc = encrypt(mkey, v);
|
||||||
aes.finish();
|
//debug("res " + a2hex(enc));
|
||||||
debug("res " + a2hex(enc));
|
|
||||||
|
|
||||||
return enc;
|
return enc;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ask_server(form, field, logins, domain, wdomain, mkey, salt, submit)
|
async function ask_server(form, field, logins, domain, wdomain, mkey, submit)
|
||||||
{
|
{
|
||||||
var a, b;
|
account_url = await getPref("account_url");
|
||||||
|
var salt = parseURI.parseUri(account_url);
|
||||||
|
salt = salt["host"] + salt["path"];
|
||||||
|
|
||||||
mkey = pkdbf2(mkey, salt, pkdbf2_level, 256/8);
|
debug("salt " + salt);
|
||||||
|
|
||||||
|
pbkdf2_level = await getPref("pbkdf2_level");
|
||||||
|
|
||||||
|
mkey = pbkdf2(mkey, salt, pbkdf2_level);
|
||||||
|
|
||||||
keys = "";
|
keys = "";
|
||||||
for(a=0, b=logins.length; a<logins.length; a++)
|
for(a=0, b=logins.length; a<logins.length; a++)
|
||||||
{
|
{
|
||||||
enc = generate_request(domain, logins[a], mkey);
|
enc = await generate_request(domain, logins[a], mkey);
|
||||||
|
|
||||||
keys += (keys.length != 0) ? "&" : "";
|
keys += (keys.length != 0) ? "&" : "";
|
||||||
keys += "k" + a + "=" + a2hex(enc);
|
keys += "k" + a + "=" + a2hex(enc);
|
||||||
|
|
||||||
if (wdomain != "")
|
if (wdomain != "")
|
||||||
{
|
{
|
||||||
enc = generate_request(wdomain, logins[a], mkey);
|
enc = await generate_request(wdomain, logins[a], mkey);
|
||||||
|
|
||||||
keys += (keys.length != 0) ? "&" : "";
|
keys += (keys.length != 0) ? "&" : "";
|
||||||
keys += "k" + (b++) + "=" + a2hex(enc);
|
keys += "k" + (b++) + "=" + a2hex(enc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,9 +92,9 @@ function ask_server(form, field, logins, domain, wdomain, mkey, salt, submit)
|
||||||
var ret = SERVER.OK;
|
var ret = SERVER.OK;
|
||||||
|
|
||||||
// gPassRequest.addEventListener("progress", function(evt) { ; }, false);
|
// gPassRequest.addEventListener("progress", function(evt) { ; }, false);
|
||||||
gPassRequest.addEventListener("load", function(evt) {
|
gPassRequest.addEventListener("load", async function(evt) {
|
||||||
var ciphered_password = "";
|
var ciphered_password = "";
|
||||||
var server_pkdbf2_level = 0;
|
var server_pbkdf2_level = 0;
|
||||||
var server_version = 0;
|
var server_version = 0;
|
||||||
|
|
||||||
var r = this.responseText.split("\n");
|
var r = this.responseText.split("\n");
|
||||||
|
@ -158,7 +139,7 @@ function ask_server(form, field, logins, domain, wdomain, mkey, salt, submit)
|
||||||
switch (server_protocol_version)
|
switch (server_protocol_version)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
server_pkdbf2_level = 1000;
|
server_pbkdf2_level = 1000;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// Version 3 : nothing special to do
|
// Version 3 : nothing special to do
|
||||||
|
@ -169,15 +150,15 @@ function ask_server(form, field, logins, domain, wdomain, mkey, salt, submit)
|
||||||
case "pass":
|
case "pass":
|
||||||
ciphered_password = params[1];
|
ciphered_password = params[1];
|
||||||
break;
|
break;
|
||||||
case "pkdbf2_level":
|
case "pbkdf2_level":
|
||||||
server_pkdbf2_level = parseInt(params[1].match(/\d+/)[0], 10);
|
server_pbkdf2_level = parseInt(params[1].match(/\d+/)[0], 10);
|
||||||
if (server_pkdbf2_level != NaN &&
|
if (server_pbkdf2_level != NaN &&
|
||||||
server_pkdbf2_level != pkdbf2_level &&
|
server_pbkdf2_level != pbkdf2_level &&
|
||||||
server_pkdbf2_level >= 1000) // Minimum level for PKDBF2 !
|
server_pbkdf2_level >= 1000) // Minimum level for PBKDF2 !
|
||||||
{
|
{
|
||||||
debug("New pkdbf2 level " + server_pkdbf2_level);
|
debug("New pbkdf2 level " + server_pbkdf2_level);
|
||||||
pkdbf2_level = server_pkdbf2_level;
|
pbkdf2_level = server_pbkdf2_level;
|
||||||
setPref("pkdbf2_level", pkdbf2_level);
|
setPref("pbkdf2_level", pbkdf2_level);
|
||||||
ret = SERVER.RESTART_REQUEST;
|
ret = SERVER.RESTART_REQUEST;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -199,8 +180,7 @@ function ask_server(form, field, logins, domain, wdomain, mkey, salt, submit)
|
||||||
if (ciphered_password != "")
|
if (ciphered_password != "")
|
||||||
{
|
{
|
||||||
debug("Ciphered password : " + ciphered_password);
|
debug("Ciphered password : " + ciphered_password);
|
||||||
clear_password = aes.decryptLongString(hex2a(ciphered_password), aes.init(mkey));
|
clear_password = await decrypt(mkey, hex2a(ciphered_password));
|
||||||
aes.finish();
|
|
||||||
// Remove trailing \0 and salt
|
// Remove trailing \0 and salt
|
||||||
clear_password = clear_password.replace(/\0*$/, "");
|
clear_password = clear_password.replace(/\0*$/, "");
|
||||||
clear_password = clear_password.substr(0, clear_password.length-3);
|
clear_password = clear_password.substr(0, clear_password.length-3);
|
||||||
|
@ -234,8 +214,8 @@ function ask_server(form, field, logins, domain, wdomain, mkey, salt, submit)
|
||||||
notify("Error",
|
notify("Error",
|
||||||
"Error");
|
"Error");
|
||||||
}, false);
|
}, false);
|
||||||
debug("connect to " + getPref("account_url"));
|
debug("connect to " + await getPref("account_url"));
|
||||||
gPassRequest.open("POST", getPref("account_url"), true);
|
gPassRequest.open("POST", await getPref("account_url"), true);
|
||||||
gPassRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
|
gPassRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
|
||||||
gPassRequest.send(keys);
|
gPassRequest.send(keys);
|
||||||
|
|
||||||
|
@ -316,11 +296,6 @@ function on_sumbit(e)
|
||||||
domain = domain["host"];
|
domain = domain["host"];
|
||||||
var wdomain = wildcard_domain(domain);
|
var wdomain = wildcard_domain(domain);
|
||||||
|
|
||||||
var salt = parseURI.parseUri(getPref("account_url"));
|
|
||||||
salt = salt["host"] + salt["path"];
|
|
||||||
|
|
||||||
debug("salt " + salt);
|
|
||||||
|
|
||||||
type_filters = new Array();
|
type_filters = new Array();
|
||||||
// Get all <input type="text"> && <input type="email">
|
// Get all <input type="text"> && <input type="email">
|
||||||
type_filters.push("text");
|
type_filters.push("text");
|
||||||
|
@ -350,8 +325,9 @@ function on_sumbit(e)
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
var ret = ask_server(form, field, logins, domain, wdomain, mkey, salt, (password.indexOf("@@") == 0));
|
var ret = ask_server(form, field, logins, domain, wdomain, mkey, (password.indexOf("@@") == 0));
|
||||||
|
|
||||||
|
ret.then(function(ret){
|
||||||
switch(ret)
|
switch(ret)
|
||||||
{
|
{
|
||||||
case SERVER.OK:
|
case SERVER.OK:
|
||||||
|
@ -359,15 +335,15 @@ function on_sumbit(e)
|
||||||
case SERVER.FAILED:
|
case SERVER.FAILED:
|
||||||
if (logins !== all_logins)
|
if (logins !== all_logins)
|
||||||
{
|
{
|
||||||
ret = ask_server(form, field, all_logins, domain, wdomain, mkey, salt, (password.indexOf("@@") == 0));
|
/*ret = */ask_server(form, field, all_logins, domain, wdomain, mkey, (password.indexOf("@@") == 0));
|
||||||
if (ret == SERVER.OK)
|
/*if (ret == SERVER.OK)
|
||||||
break;
|
break;};*/
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SERVER.RESTART_REQUEST:
|
case SERVER.RESTART_REQUEST:
|
||||||
i = -1; // Restart loop
|
i = -1; // Restart loop
|
||||||
break;
|
break;
|
||||||
}
|
}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,24 +369,21 @@ function document_loaded(doc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function init(prefs)
|
document_loaded(document);
|
||||||
{
|
|
||||||
for (k in prefs)
|
|
||||||
preferences[k] = prefs[k];
|
|
||||||
pkdbf2_level = getPref("pkdbf2_level");
|
|
||||||
document_loaded(document);
|
|
||||||
}
|
|
||||||
|
|
||||||
// First, load preferences
|
async function self_test()
|
||||||
chrome.storage.local.get(null, init);
|
|
||||||
|
|
||||||
function self_test()
|
|
||||||
{
|
{
|
||||||
if((res = a2hex(pkdbf2("password", "salt", 4096, 256/8))) !=
|
mkey = pbkdf2("password", "salt", 4096);
|
||||||
"c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a")
|
res = await encrypt(mkey, "DDDDDDDDDDDDDDDD");
|
||||||
console.log("PKDBF2 failed " + res);
|
reference = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
|
if (res != ab2str(reference))
|
||||||
|
{
|
||||||
|
console.log("Self test ERROR ! ");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
console.log("All is OK ! ");
|
console.log("All is OK ! ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// self_test();
|
// self_test();
|
||||||
|
|
||||||
|
getPref("account_url");
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
"matches": ["https://*/*", "http://*/*"],
|
"matches": ["https://*/*", "http://*/*"],
|
||||||
"js": ["lib/parseuri.js", "lib/jsaes.js", "lib/jssha256.js", "lib/hmac.js", "lib/pkdbf2.js", "lib/main.js"],
|
"js": ["lib/parseuri.js", "lib/jsaes.js", "lib/jssha256.js", "lib/hmac.js", "lib/pkdbf2.js", "compat.js", "lib/main.js"],
|
||||||
"run_at" : "document_idle",
|
"run_at" : "document_idle",
|
||||||
"all_frames" : true
|
"all_frames" : true
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<b>Account URL</b> URL of your gPass account <input id="account_url" type="text"/><br />
|
<b>Account URL</b> URL of your gPass account <input id="account_url" type="text"/><br />
|
||||||
<b>WARNING</b> It should be a valid HTTPS URL because doesn't like mixed content (https/http) with a recognized certificate. Of not, requests will silentely failed. If you have an auto-signed certificate, add it to trusted ones.<br/>
|
<b>WARNING</b> It should be a valid HTTPS URL because navigator doesn't like mixed content (HTTPS/HTTP). If not, requests will silentely failed. If you have an auto-signed certificate, add it to trusted ones.<br/>
|
||||||
<br/>
|
<br/>
|
||||||
<b>PKDBF2 level</b> Number of iterations used to derivate master key <input id="pkdbf2" type="number"/><br />
|
<b>PBKDF2 level</b> Number of iterations used to derivate master key <input id="pbkdf2" type="number"/><br />
|
||||||
<br/>
|
<br/>
|
||||||
<input type="button" id="save" value="Save"/>
|
<input type="button" id="save" value="Save"/>
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
var default_preferences = {"pkdbf2_level": 1000,
|
var default_preferences = {"pbkdf2_level": 1000,
|
||||||
"account_url": "https://gpass-demo.soutade.fr/demo"};
|
"account_url": "https://gpass-demo.soutade.fr/demo"};
|
||||||
|
|
||||||
function save() {
|
function save() {
|
||||||
var account_url = document.getElementById('account_url').value;
|
var account_url = document.getElementById('account_url').value;
|
||||||
var pkdbf2 = document.getElementById('pkdbf2').value;
|
var pbkdf2 = document.getElementById('pbkdf2').value;
|
||||||
|
|
||||||
chrome.storage.local.set({
|
chrome.storage.local.set({
|
||||||
'account_url': account_url,
|
'account_url': account_url,
|
||||||
'pkdbf2': pkdbf2,
|
'pbkdf2': pbkdf2,
|
||||||
}, function() {
|
}, function() {
|
||||||
alert('Saved');
|
alert('Saved');
|
||||||
});
|
});
|
||||||
|
@ -19,13 +19,13 @@ chrome.storage.local.get(null, function(prefs) {
|
||||||
else
|
else
|
||||||
account_url = prefs['account_url'];
|
account_url = prefs['account_url'];
|
||||||
|
|
||||||
if (!prefs.hasOwnProperty("pkdbf2_level"))
|
if (!prefs.hasOwnProperty("pbkdf2_level"))
|
||||||
pkdbf2 = default_preferences['pkdbf2_level'];
|
pbkdf2 = default_preferences['pbkdf2_level'];
|
||||||
else
|
else
|
||||||
pkdbf2 = prefs['pkdbf2_level'];
|
pbkdf2 = prefs['pbkdf2_level'];
|
||||||
|
|
||||||
document.getElementById('account_url').value = account_url;
|
document.getElementById('account_url').value = account_url;
|
||||||
document.getElementById('pkdbf2').value = pkdbf2;
|
document.getElementById('pbkdf2').value = pbkdf2;
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('save').addEventListener("click", save);
|
document.getElementById('save').addEventListener("click", save);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user