Changes to database storing in the plugin

This commit is contained in:
varjolintu 2017-04-03 09:57:30 +03:00
parent a36545e68e
commit 375a9e8d4a
9 changed files with 235 additions and 250 deletions

View file

@ -28,6 +28,7 @@ Now the requests are encrypted by [TweetNaCl.js](https://github.com/dchest/tweet
3. All messages (excluding get-databasehash) are now encrypted.
4. When chromeKeePassXC sends a message it is encrypted with KeePassXC's public key, a random generated nonce and chromeKeePassXC's secret key.
5. When KeePassXC sends a message it is encrypted with chromeKeePassXC's public key etc.
6. Databases are stored based on the database hash instead of the key because a new key pair is generated each time chromeKeePassXC is launched.
Encrypted messages are built with these JSON parameters:
- action - `test-associate`, `associate`, `get-logins`, `get-logins-count`, `set-login`...

View file

@ -5,7 +5,7 @@ event.onMessage = function(request, sender, callback) {
if (request.action in event.messageHandlers) {
//console.log("onMessage(" + request.action + ") for #" + sender.tab.id);
if(!sender.hasOwnProperty('tab') || sender.tab.id < 1) {
if (!sender.hasOwnProperty('tab') || sender.tab.id < 1) {
sender.tab = {};
sender.tab.id = page.currentTabId;
}
@ -14,7 +14,7 @@ event.onMessage = function(request, sender, callback) {
// onMessage closes channel for callback automatically
// if this method does not return true
if(callback) {
if (callback) {
return true;
}
}
@ -32,11 +32,11 @@ event.onMessage = function(request, sender, callback) {
* @returns null (asynchronous)
*/
event.invoke = function(handler, callback, senderTabId, args, secondTime) {
if(senderTabId < 1) {
if (senderTabId < 1) {
return;
}
if(!page.tabs[senderTabId]) {
if (!page.tabs[senderTabId]) {
page.createTabEntry(senderTabId);
}
@ -49,7 +49,7 @@ event.invoke = function(handler, callback, senderTabId, args, secondTime) {
// return; // For example: only the background devtools or a popup are opened
//var tab = tabs[0];
if(!tab) {
if (!tab) {
return;
}
@ -64,7 +64,7 @@ event.invoke = function(handler, callback, senderTabId, args, secondTime) {
return;
}
if(!page.tabs[tab.id]) {
if (!page.tabs[tab.id]) {
page.createTabEntry(tab.id);
}
@ -73,7 +73,7 @@ event.invoke = function(handler, callback, senderTabId, args, secondTime) {
args.unshift(tab);
args.unshift(callback);
if(handler) {
if (handler) {
handler.apply(this, args);
}
else {
@ -84,7 +84,7 @@ event.invoke = function(handler, callback, senderTabId, args, secondTime) {
event.onShowAlert = function(callback, tab, message) {
if( page.settings.supressAlerts ){ console.log(message); }
if (page.settings.supressAlerts) { console.log(message); }
else { alert(message); }
}
@ -94,7 +94,7 @@ event.onLoadSettings = function(callback, tab) {
event.onLoadKeyRing = function(callback, tab) {
keepass.keyRing = (typeof(localStorage.keyRing) == 'undefined') ? {} : JSON.parse(localStorage.keyRing);
if(keepass.isAssociated() && !keepass.keyRing[keepass.associated.hash]) {
if (keepass.isAssociated() && !keepass.keyRing[keepass.associated.hash]) {
keepass.associated = {
"value": false,
"hash": null
@ -122,7 +122,7 @@ event.onGetStatus = function(callback, tab) {
}
browserAction.showDefault(null, tab);
console.log(page.tabs[tab.id].errorMessage);
callback({
identifier: keyId,
configured: configured,
@ -153,7 +153,7 @@ event.onGetConnectedDatabase = function(callback, tab) {
}
event.onGetKeePassXCVersions = function(callback, tab) {
if(keepass.currentKeePassXC.version == 0) {
if (keepass.currentKeePassXC.version == 0) {
keepass.getDatabaseHash(tab);
}
callback({"current": keepass.currentKeePassXC.version, "latest": keepass.latestKeePassXC.version});

View file

@ -8,7 +8,7 @@ page.initOpenedTabs();
keepass.connectToNative();
keepass.generateNewKeyPair();
keepass.getDatabaseHash(null);
keepass.changePublicKeys();
keepass.changePublicKeys(null);
// set initial tab-ID
chrome.tabs.query({"active": true, "windowId": chrome.windows.WINDOW_ID_CURRENT}, function(tabs) {
if (tabs.length === 0)

View file

@ -6,7 +6,6 @@ keepass.serverPublicKey = "";
keepass.isConnected = false;
keepass.isDatabaseClosed = false;
keepass.isKeePassXCAvailable = false;
keepass.useBox = false;
keepass.isEncryptionKeyUnrecognized = false;
keepass.currentKeePassXC = {"version": 0, "versionParsed": 0};
keepass.latestKeePassXC = (typeof(localStorage.latestKeePassXC) == 'undefined') ? {"version": 0, "versionParsed": 0, "lastChecked": null} : JSON.parse(localStorage.latestKeePassXC);
@ -36,7 +35,7 @@ keepass.updateCredentials = function(callback, tab, entryId, username, password,
page.tabs[tab.id].errorMessage = null;
// is browser associated to keepass?
if(!keepass.testAssociation(tab)) {
if (!keepass.testAssociation(tab)) {
browserAction.showDefault(null, tab);
callback("error");
return;
@ -97,7 +96,7 @@ keepass.retrieveCredentials = function (callback, tab, url, submiturl, forceCall
page.debug("keepass.retrieveCredentials(callback, {1}, {2}, {3}, {4})", tab.id, url, submiturl, forceCallback);
// is browser associated to keepass?
if(!keepass.testAssociation(tab)) {
if (!keepass.testAssociation(tab)) {
browserAction.showDefault(null, tab);
callback("error");
return;
@ -203,13 +202,13 @@ keepass.generatePassword = function (callback, tab, forceCallback) {
}
// is browser associated to keepass?
if(!keepass.testAssociation(tab)) {
if (!keepass.testAssociation(tab)) {
browserAction.showDefault(null, tab);
callback("error");
return;
}
if(keepass.currentKeePassXC.versionParsed < keepass.requiredKeePassXC) {
if (keepass.currentKeePassXC.versionParsed < keepass.requiredKeePassXC) {
callback([]);
return;
}
@ -247,7 +246,7 @@ keepass.generatePassword = function (callback, tab, forceCallback) {
var rIv = response.nonce;
// var response = JSON.stringify({ Login: (msg.password.length * 8), Password: msg.password });
if(parsed.entries) {
if (parsed.entries) {
passwords = parsed.entries;
keepass.updateLastUsed(keepass.databaseHash);
}
@ -268,7 +267,7 @@ keepass.generatePassword = function (callback, tab, forceCallback) {
keepass.copyPassword = function(callback, tab, password) {
var bg = chrome.extension.getBackgroundPage();
var c2c = bg.document.getElementById("copy2clipboard");
if(!c2c) {
if (!c2c) {
var input = document.createElement('input');
input.type = "text";
input.id = "copy2clipboard";
@ -284,13 +283,13 @@ keepass.copyPassword = function(callback, tab, password) {
}
keepass.associate = function(callback, tab) {
if(keepass.isAssociated()) {
if (keepass.isAssociated()) {
return;
}
keepass.getDatabaseHash(callback, tab);
if(keepass.isDatabaseClosed || !keepass.isKeePassXCAvailable) {
if (keepass.isDatabaseClosed || !keepass.isKeePassXCAvailable) {
return;
}
@ -330,7 +329,7 @@ keepass.associate = function(callback, tab) {
}
var id = parsed.id;
if(!keepass.verifyResponse(parsed, response.nonce)) {
if (!keepass.verifyResponse(parsed, response.nonce)) {
page.tabs[tab.id].errorMessage = "KeePassXC association failed, try again.";
}
else {
@ -350,11 +349,11 @@ keepass.associate = function(callback, tab) {
keepass.testAssociation = function (tab, triggerUnlock) {
keepass.getDatabaseHash(null, tab, triggerUnlock);
if(keepass.isDatabaseClosed || !keepass.isKeePassXCAvailable) {
if (keepass.isDatabaseClosed || !keepass.isKeePassXCAvailable) {
return false;
}
if(keepass.isAssociated()) {
if (keepass.isAssociated()) {
return true;
}
@ -394,7 +393,7 @@ keepass.testAssociation = function (tab, triggerUnlock) {
var id = parsed.id;
keepass.isEncryptionKeyUnrecognized = false;
if(!keepass.verifyResponse(parsed, response.nonce)) {
if (!keepass.verifyResponse(parsed, response.nonce)) {
var hash = response.hash || 0;
keepass.deleteKey(hash);
keepass.isEncryptionKeyUnrecognized = true;
@ -403,15 +402,19 @@ keepass.testAssociation = function (tab, triggerUnlock) {
keepass.associated.value = false;
keepass.associated.hash = null;
}
else if(!keepass.isAssociated()) {
else if (!keepass.isAssociated()) {
console.log("Association was not successful");
page.tabs[tab.id].errorMessage = "Association was not successful.";
}
else {
if (tab && page.tabs[tab.id]) {
delete page.tabs[tab.id].errorMessage;
}
}
}
}
});
keepass.nativePort.postMessage(request);
return keepass.isAssociated();
}
@ -427,11 +430,15 @@ keepass.getDatabaseHash = function (callback, tab, triggerUnlock) {
keepass.setcurrentKeePassXCVersion(response.version);
keepass.databaseHash = response.hash || "no-hash";
if(oldDatabaseHash && oldDatabaseHash != keepass.databaseHash) {
if (oldDatabaseHash && oldDatabaseHash != keepass.databaseHash) {
keepass.associated.value = false;
keepass.associated.hash = null;
}
if (tab && page.tabs[tab.id]) {
delete page.tabs[tab.id].errorMessage;
}
statusOK();
return keepass.databaseHash;
});
@ -463,7 +470,7 @@ keepass.changePublicKeys = function() {
}
var id = response.id;
if(!keepass.verifyKeyResponse(response, key, nonce)) {
if (!keepass.verifyKeyResponse(response, key, nonce)) {
console.log("Error");
}
else {
@ -488,7 +495,7 @@ keepass.generateNewKeyPair = function() {
}
keepass.isConfigured = function() {
if(typeof(keepass.databaseHash) == "undefined") {
if (typeof(keepass.databaseHash) == "undefined") {
keepass.getDatabaseHash();
}
return (keepass.databaseHash in keepass.keyRing);
@ -504,27 +511,27 @@ keepass.checkStatus = function (status, tab) {
keepass.isDatabaseClosed = false;
keepass.isKeePassXCAvailable = true;
if(tab && page.tabs[tab.id]) {
if (tab && page.tabs[tab.id]) {
delete page.tabs[tab.id].errorMessage;
}
if (!success) {
keepass.associated.value = false;
keepass.associated.hash = null;
if(tab && page.tabs[tab.id]) {
if (tab && page.tabs[tab.id]) {
page.tabs[tab.id].errorMessage = "Unknown error: " + status;
}
console.log("Error: "+ status);
if (status == 503) {
keepass.isDatabaseClosed = true;
console.log("KeePass database is not opened");
if(tab && page.tabs[tab.id]) {
if (tab && page.tabs[tab.id]) {
page.tabs[tab.id].errorMessage = "KeePass database is not opened.";
}
}
else if (status == 0) {
keepass.isKeePassXCAvailable = false;
console.log("Could not connect to keepass");
if(tab && page.tabs[tab.id]) {
if (tab && page.tabs[tab.id]) {
page.tabs[tab.id].errorMessage = "Is KeePassXC installed and running?";
}
}
@ -536,7 +543,7 @@ keepass.checkStatus = function (status, tab) {
}
keepass.convertKeyToKeyRing = function() {
if(keepass.keyId in localStorage && keepass.keyBody in localStorage && !("keyRing" in localStorage)) {
if (keepass.keyId in localStorage && keepass.keyBody in localStorage && !("keyRing" in localStorage)) {
keepass.getDatabaseHash(function(hash) {
keepass.saveKey(hash, localStorage[keepass.keyId], localStorage[keepass.keyBody]);
}, null);
@ -549,7 +556,7 @@ keepass.convertKeyToKeyRing = function() {
}
keepass.saveKey = function(hash, id, key) {
if(!(hash in keepass.keyRing)) {
if (!(hash in keepass.keyRing)) {
keepass.keyRing[hash] = {
"id": id,
//"key": key,
@ -568,7 +575,7 @@ keepass.saveKey = function(hash, id, key) {
}
keepass.updateLastUsed = function(hash) {
if((hash in keepass.keyRing)) {
if ((hash in keepass.keyRing)) {
keepass.keyRing[hash].lastUsed = new Date();
localStorage.keyRing = JSON.stringify(keepass.keyRing);
}
@ -584,7 +591,7 @@ keepass.getIconColor = function() {
}
keepass.setcurrentKeePassXCVersion = function(version) {
if(version) {
if (version) {
keepass.currentKeePassXC = {
"version": version,
"versionParsed": parseInt(version.replace(/\./g,""))
@ -593,10 +600,10 @@ keepass.setcurrentKeePassXCVersion = function(version) {
}
keepass.keePassXCUpdateAvailable = function() {
if(page.settings.checkUpdateKeePassXC && page.settings.checkUpdateKeePassXC > 0) {
if (page.settings.checkUpdateKeePassXC && page.settings.checkUpdateKeePassXC > 0) {
var lastChecked = (keepass.latestKeePassXC.lastChecked) ? new Date(keepass.latestKeePassXC.lastChecked) : new Date("11/21/1986");
var daysSinceLastCheck = Math.floor(((new Date()).getTime()-lastChecked.getTime())/86400000);
if(daysSinceLastCheck >= page.settings.checkUpdateKeePassXC) {
if (daysSinceLastCheck >= page.settings.checkUpdateKeePassXC) {
keepass.checkForNewKeePassXCVersion();
}
}
@ -611,7 +618,7 @@ keepass.checkForNewKeePassXCVersion = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var $version = xhr.responseText;
if($version.substring(0, 1) == "2") {
if ($version.substring(0, 1) == "2") {
$version = $version.substring(0, $version.indexOf(" "));
keepass.latestKeePassXC.version = $version;
keepass.latestKeePassXC.versionParsed = parseInt($version.replace(/\./g,""));
@ -622,7 +629,7 @@ keepass.checkForNewKeePassXCVersion = function() {
}
}
if($version != -1) {
if ($version != -1) {
localStorage.latestKeePassXC = JSON.stringify(keepass.latestKeePassXC);
}
};
@ -668,7 +675,7 @@ keepass.setVerifier = function(request, inputKey) {
var key = inputKey || null;
var id = null;
if(!key) {
if (!key) {
var info = keepass.getCryptoKey();
if (info == null) {
return null;
@ -677,7 +684,7 @@ keepass.setVerifier = function(request, inputKey) {
key = info[1];
}
if(id) {
if (id) {
request.id = id;
}
@ -725,7 +732,7 @@ keepass.verifyResponse = function(response, nonce, id) {
keepass.associated.value = (response.nonce == nonce);
if(id) {
if (id) {
keepass.associated.value = (keepass.associated.value && id == response.id);
}
@ -744,14 +751,14 @@ keepass.b64d = function(d) {
}
keepass.getCryptoKey = function() {
if(!(keepass.databaseHash in keepass.keyRing)) {
if (!(keepass.databaseHash in keepass.keyRing)) {
return null;
}
var id = keepass.keyRing[keepass.databaseHash].id;
var key = null;
if(id) {
if (id) {
//key = keepass.keyRing[keepass.databaseHash].key;
key = keepass.b64e(keepass.keyPair.publicKey);
}

View file

@ -27,12 +27,6 @@ page.initSettings = function() {
if(!("autoRetrieveCredentials" in page.settings)) {
page.settings.autoRetrieveCredentials = 1;
}
if(!("hostname" in page.settings)) {
page.settings.hostname = "localhost";
}
if(!("port" in page.settings)) {
page.settings.port = "19455";
}
localStorage.settings = JSON.stringify(page.settings);
}

File diff suppressed because it is too large Load diff

View file

@ -107,6 +107,7 @@
<input type="checkbox" name="autoFillSingleEntry" value="1" /> Automatically fill-in single credentials entry.
</label>
<span class="help-block">If chromeKeePassXC does only receive a single entry from KeePassXC it automatically fills this credentials into the found credential fields.</span>
<span class="bg-danger">Warning! Using auto-fill is not safe. Use at your own risk.</span>
</div>
</p>
<hr />
@ -162,15 +163,13 @@
<h2>Connected Databases</h2>
<hr />
<p>
If you are using several KeePass databases you can define a specific icon-color to each of them.
<br />
This will help you to easily determine from which database the credentials are retrieved.
The following KeePassXC databases are connected to chromeKeePassXC.
</p>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Identifier</th>
<th>Icon</th>
<th>Hash</th>
<th>Last used</th>
<th>Created</th>
<th>Delete</th>

View file

@ -73,8 +73,6 @@ options.initGeneralSettings = function() {
$("#dangerousSettings").toggle();
});
$("#hostname").val(options.settings["hostname"]);
$("#port").val(options.settings["port"]);
$("#blinkTimeout").val(options.settings["blinkTimeout"]);
$("#blinkMinTimeout").val(options.settings["blinkMinTimeout"]);
$("#allowedRedirect").val(options.settings["allowedRedirect"]);
@ -172,20 +170,6 @@ options.initConnectedDatabases = function() {
$("#tab-connected-databases tr.clone:first .dropdown-menu:first").width("230px");
$("#tab-connected-databases tr.clone:first .color.dropdown .dropdown-menu a").click(function(e) {
e.preventDefault();
var $icon = $(this).attr("href").substring(1);
var $hash = $(this).closest("tr").data("hash");
$(this).parent().parent().find("a.dropdown-toggle:first").find("img:first").attr("src", "/icons/19x19/icon_normal_" + $icon + "_19x19.png");
options.keyRing[$hash].icon = $icon;
localStorage.keyRing = JSON.stringify(options.keyRing);
chrome.extension.sendMessage({
action: 'load_keyring'
});
});
var $trClone = $("#tab-connected-databases table tr.clone:first").clone(true);
$trClone.removeClass("clone");
for(var hash in options.keyRing) {
@ -197,6 +181,7 @@ options.initConnectedDatabases = function() {
$("a.dropdown-toggle:first img:first", $tr).attr("src", "/icons/19x19/icon_normal_" + $icon + "_19x19.png");
$tr.children("td:first").text(options.keyRing[hash].id);
$tr.children("td:eq(1)").text(hash);
var lastUsed = (options.keyRing[hash].lastUsed) ? new Date(options.keyRing[hash].lastUsed).toLocaleString() : "unknown";
$tr.children("td:eq(2)").text(lastUsed);
var date = (options.keyRing[hash].created) ? new Date(options.keyRing[hash].created).toLocaleDateString() : "unknown";

View file

@ -6,7 +6,6 @@ function status_response(r) {
$('#configured-and-associated').hide();
$('#configured-not-associated').hide();
if(!r.keePassXCAvailable || r.databaseClosed) {
$('#error-message').html(r.error);
$('#error-encountered').show();