From 20bea94ab6b91c85b171dcf86baba0a64169d508 Mon Sep 17 00:00:00 2001 From: Giulio Cesare Solaroli Date: Fri, 30 Aug 2013 15:56:53 +0000 Subject: First release of /delta version --- (limited to 'frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js') diff --git a/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js new file mode 100644 index 0000000..a3c238c --- a/dev/null +++ b/frontend/delta/js/Clipperz/PM/Proxy/Proxy.Offline.LocalStorageDataStore.js @@ -0,0 +1,420 @@ +/* + +Copyright 2008-2013 Clipperz Srl + +This file is part of Clipperz, the online password manager. +For further information about its features and functionalities please +refer to http://www.clipperz.com. + +* Clipperz is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + +* Clipperz is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Affero General Public License for more details. + +* You should have received a copy of the GNU Affero General Public + License along with Clipperz. If not, see http://www.gnu.org/licenses/. + +*/ + +try { if (typeof(Clipperz.PM.Proxy.Offline.DataStore) == 'undefined') { throw ""; }} catch (e) { + throw "Clipperz.PM.Proxy.Offline.LocalStorageDataStore depends on Clipperz.PM.Proxy.Offline.DataStore!"; +} + +//============================================================================= + +Clipperz.PM.Proxy.Offline.LocalStorageDataStore = function(args) { + args = args || {}; + + this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null); + this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly); + this._shouldPayTolls = args.shouldPayTolls || false; + + this._tolls = {}; + this._currentStaticConnection = null; + +// Clipperz.PM.Proxy.Offline.LocalStorageDataStore.superclass.constructor.apply(this, arguments); + + return this; +} + +Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.LocalStorageDataStore, Clipperz.PM.Proxy.Offline.DataStore, { + + //========================================================================= + + '_knock': function(aConnection, someParameters) { + var result; + + result = { + toll: this.getTollForRequestType(someParameters['requestType']) + } + + return result; + }, + + //------------------------------------------------------------------------- + + '_registration': function(aConnection, someParameters) { + throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; + }, + + //------------------------------------------------------------------------- + + '_handshake': function(aConnection, someParameters) { + var result; + var nextTollRequestType; + + result = {}; + if (someParameters.message == "connect") { + var userData; + var randomBytes; + var v; + + userData = this.data()['users'][someParameters.parameters.C]; + + if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) { + aConnection['userData'] = userData; + aConnection['C'] = someParameters.parameters.C; + } else { + aConnection['userData'] = this.data()['users']['catchAllUser']; + } + + randomBytes = Clipperz.Crypto.Base.generateRandomSeed(); + aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16); + v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); + aConnection['B'] = v.add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n())); + + aConnection['A'] = someParameters.parameters.A; + + result['s'] = aConnection['userData']['s']; + result['B'] = aConnection['B'].asString(16); + + nextTollRequestType = 'CONNECT'; + } else if (someParameters.message == "credentialCheck") { + var v, u, S, A, K, M1; + + v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16); + u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aConnection['B'].asString(10))).toHexString(), 16); + A = new Clipperz.Crypto.BigInt(aConnection['A'], 16); + S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()); + + K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2); + + M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10) + K)).toHexString().slice(2); + if (someParameters.parameters.M1 == M1) { + var M2; + + M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2); + result['M2'] = M2; + } else { + throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error"); + } + + nextTollRequestType = 'MESSAGE'; + } else if (someParameters.message == "oneTimePassword") { + var otpData; + + otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey]; + + try { + if (typeof(otpData) != 'undefined') { + if (otpData['status'] == 'ACTIVE') { + if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { + result = { + 'data': otpData['data'], + 'version': otpData['version'] + } + + otpData['status'] = 'REQUESTED'; + } else { + otpData['status'] = 'DISABLED'; + throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; + } + } else { + throw "The requested One Time Password was not active"; + } + } else { + throw "The requested One Time Password has not been found" + } + } catch (exception) { + result = { + 'data': Clipperz.PM.Crypto.randomKey(), + 'version': Clipperz.PM.Connection.communicationProtocol.currentVersion + } + } + nextTollRequestType = 'CONNECT'; + } else { + Clipperz.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message); + } + + result = { + result: result, + toll: this.getTollForRequestType(nextTollRequestType) + } + + return result; + }, + + //------------------------------------------------------------------------- + + '_message': function(aConnection, someParameters) { + var result; + + result = {}; + + //===================================================================== + // + // R E A D - O N L Y M e t h o d s + // + //===================================================================== + if (someParameters.message == 'getUserDetails') { + var recordsStats; + var recordReference; + + recordsStats = {}; + for (recordReference in aConnection['userData']['records']) { + recordsStats[recordReference] = { + 'updateDate': aConnection['userData']['records'][recordReference]['updateDate'] + } + } + + result['header'] = this.userDetails(aConnection); + result['statistics'] = this.statistics(aConnection); + result['maxNumberOfRecords'] = aConnection['userData']['maxNumberOfRecords']; + result['version'] = aConnection['userData']['userDetailsVersion']; + result['recordsStats'] = recordsStats; + + if (this.isReadOnly() == false) { + var lock; + + if (typeof(aConnection['userData']['lock']) == 'undefined') { + aConnection['userData']['lock'] = "<>"; + } + + result['lock'] = aConnection['userData']['lock']; + } + + //===================================================================== + } else if (someParameters.message == 'getRecordDetail') { +/* + var recordData; + var currentVersionData; + + recordData = this.userData()['records'][someParameters['parameters']['reference']]; + result['reference'] = someParameters['parameters']['reference']; + result['data'] = recordData['data']; + result['version'] = recordData['version']; + result['creationData'] = recordData['creationDate']; + result['updateDate'] = recordData['updateDate']; + result['accessDate'] = recordData['accessDate']; + + currentVersionData = recordData['versions'][recordData['currentVersion']]; + + result['currentVersion'] = {}; + result['currentVersion']['reference'] = recordData['currentVersion']; + result['currentVersion']['version'] = currentVersionData['version']; + result['currentVersion']['header'] = currentVersionData['header']; + result['currentVersion']['data'] = currentVersionData['data']; + result['currentVersion']['creationData'] = currentVersionData['creationDate']; + result['currentVersion']['updateDate'] = currentVersionData['updateDate']; + result['currentVersion']['accessDate'] = currentVersionData['accessDate']; + if (typeof(currentVersionData['previousVersion']) != 'undefined') { + result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey']; + result['currentVersion']['previousVersion'] = currentVersionData['previousVersion']; + } +*/ + MochiKit.Base.update(result, aConnection['userData']['records'][someParameters['parameters']['reference']]); + result['reference'] = someParameters['parameters']['reference']; + + //===================================================================== + // + // R E A D - W R I T E M e t h o d s + // + //===================================================================== + } else if (someParameters.message == 'upgradeUserCredentials') { + if (this.isReadOnly() == false) { + var parameters; + var credentials; + + parameters = someParameters['parameters']; + credentials = parameters['credentials']; + + if ((credentials['C'] == null) + || (credentials['s'] == null) + || (credentials['v'] == null) + || (credentials['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion) + ) { + result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; + } else { + var oldCValue; + oldCValue = aConnection['C']; + + this.data()['users'][credentials['C']] = aConnection['userData']; + aConnection['C'] = credentials['C']; + + aConnection['userData']['s'] = credentials['s']; + aConnection['userData']['v'] = credentials['v']; + aConnection['userData']['version'] = credentials['version']; + + aConnection['userData']['userDetails'] = parameters['user']['header']; + aConnection['userData']['userDetailsVersion'] = parameters['user']['version']; + aConnection['userData']['statistics'] = parameters['user']['statistics']; + + aConnection['userData']['lock'] = parameters['user']['lock']; + + delete this.data()['users'][oldCValue]; + + result = {result:"done", parameters:parameters}; + } + } else { + throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; + } + + //===================================================================== + + } else if (someParameters.message == 'saveChanges') { + if (this.isReadOnly() == false) { + var i, c; + + if (aConnection['userData']['lock'] != someParameters['parameters']['user']['lock']) { + throw "the lock attribute is not processed correctly" + } + + aConnection['userData']['userDetails'] = someParameters['parameters']['user']['header']; + aConnection['userData']['statistics'] = someParameters['parameters']['user']['statistics']; + aConnection['userData']['userDetailsVersion'] = someParameters['parameters']['user']['version']; + + c = someParameters['parameters']['records']['updated'].length; + for (i=0; i