summaryrefslogtreecommitdiff
path: root/frontend/beta/js/Clipperz
Unidiff
Diffstat (limited to 'frontend/beta/js/Clipperz') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/beta/js/Clipperz/Base.js28
-rw-r--r--frontend/beta/js/Clipperz/Crypto/PRNG.js130
-rw-r--r--frontend/beta/js/Clipperz/Crypto/SRP.js67
-rw-r--r--frontend/beta/js/Clipperz/PM/BookmarkletProcessor.js2
-rw-r--r--frontend/beta/js/Clipperz/PM/Components/RecordDetail/DirectLoginBindingComponent.js4
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js22
-rw-r--r--frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js2
-rw-r--r--frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js47
8 files changed, 170 insertions, 132 deletions
diff --git a/frontend/beta/js/Clipperz/Base.js b/frontend/beta/js/Clipperz/Base.js
index cf40314..1c6faa1 100644
--- a/frontend/beta/js/Clipperz/Base.js
+++ b/frontend/beta/js/Clipperz/Base.js
@@ -57,247 +57,275 @@ MochiKit.Base.update(Clipperz.Base, {
57 57
58 c = aValue.length; 58 c = aValue.length;
59 for (i=0; i<c; i++) { 59 for (i=0; i<c; i++) {
60 result[i] = aValue.charCodeAt(i); 60 result[i] = aValue.charCodeAt(i);
61 } 61 }
62 62
63 return result; 63 return result;
64 }, 64 },
65 65
66 //......................................................................... 66 //.........................................................................
67 67
68 'byteArrayToString': function (anArrayOfBytes) { 68 'byteArrayToString': function (anArrayOfBytes) {
69 varresult; 69 varresult;
70 var i, c; 70 var i, c;
71 71
72 result = ""; 72 result = "";
73 73
74 c = anArrayOfBytes.length; 74 c = anArrayOfBytes.length;
75 for (i=0; i<c; i++) { 75 for (i=0; i<c; i++) {
76 result += String.fromCharCode(anArrayOfBytes[i]); 76 result += String.fromCharCode(anArrayOfBytes[i]);
77 } 77 }
78 78
79 return result; 79 return result;
80 }, 80 },
81 81
82 //------------------------------------------------------------------------- 82 //-------------------------------------------------------------------------
83 83
84 'getValueForKeyInFormContent': function (aFormContent, aKey) { 84 'getValueForKeyInFormContent': function (aFormContent, aKey) {
85 return aFormContent[1][MochiKit.Base.find(aFormContent[0], aKey)]; 85 return aFormContent[1][MochiKit.Base.find(aFormContent[0], aKey)];
86 }, 86 },
87 87
88 //------------------------------------------------------------------------- 88 //-------------------------------------------------------------------------
89 89
90 'indexOfObjectInArray': function(anObject, anArray) { 90 'indexOfObjectInArray': function(anObject, anArray) {
91 varresult; 91 varresult;
92 vari, c; 92 vari, c;
93 93
94 result = -1; 94 result = -1;
95 95
96 c = anArray.length; 96 c = anArray.length;
97 for (i=0; ((i<c) && (result < 0)); i++) { 97 for (i=0; ((i<c) && (result < 0)); i++) {
98 if (anArray[i] === anObject) { 98 if (anArray[i] === anObject) {
99 result = i; 99 result = i;
100 } 100 }
101 } 101 }
102 102
103 return result; 103 return result;
104 }, 104 },
105 105
106 'removeObjectAtIndexFromArray': function(anIndex, anArray) { 106 'removeObjectAtIndexFromArray': function(anIndex, anArray) {
107 anArray.splice(anIndex, 1); 107 anArray.splice(anIndex, 1);
108 }, 108 },
109 109
110 'removeObjectFromArray': function(anObject, anArray) { 110 'removeObjectFromArray': function(anObject, anArray) {
111 varobjectIndex; 111 varobjectIndex;
112 112
113 objectIndex = Clipperz.Base.indexOfObjectInArray(anObject, anArray); 113 objectIndex = Clipperz.Base.indexOfObjectInArray(anObject, anArray);
114 if (objectIndex > -1) { 114 if (objectIndex > -1) {
115 Clipperz.Base.removeObjectAtIndexFromArray(objectIndex, anArray); 115 Clipperz.Base.removeObjectAtIndexFromArray(objectIndex, anArray);
116 } else { 116 } else {
117 // jslog.error("Trying to remove an object not present in the array"); 117 // jslog.error("Trying to remove an object not present in the array");
118 //TODO: raise an exception 118 //TODO: raise an exception
119 } 119 }
120 }, 120 },
121 121
122 'removeFromArray': function(anArray, anObject) { 122 'removeFromArray': function(anArray, anObject) {
123 return Clipperz.Base.removeObjectFromArray(anObject, anArray); 123 return Clipperz.Base.removeObjectFromArray(anObject, anArray);
124 }, 124 },
125 125
126 //------------------------------------------------------------------------- 126 //-------------------------------------------------------------------------
127 127
128 'splitStringAtFixedTokenSize': function(aString, aTokenSize) { 128 'splitStringAtFixedTokenSize': function(aString, aTokenSize) {
129 var result; 129 var result;
130 varstringToProcess; 130 varstringToProcess;
131 131
132 stringToProcess = aString; 132 stringToProcess = aString;
133 result = []; 133 result = [];
134 if (stringToProcess != null) { 134 if (stringToProcess != null) {
135 while (stringToProcess.length > aTokenSize) { 135 while (stringToProcess.length > aTokenSize) {
136 result.push(stringToProcess.substring(0, aTokenSize)); 136 result.push(stringToProcess.substring(0, aTokenSize));
137 stringToProcess = stringToProcess.substring(aTokenSize); 137 stringToProcess = stringToProcess.substring(aTokenSize);
138 } 138 }
139 139
140 result.push(stringToProcess); 140 result.push(stringToProcess);
141 } 141 }
142 142
143 return result; 143 return result;
144 }, 144 },
145 145
146 //------------------------------------------------------------------------- 146 //-------------------------------------------------------------------------
147 147
148 'objectType': function(anObject) { 148 'objectType': function(anObject) {
149 var result; 149 var result;
150 150
151 if (anObject == null) { 151 if (anObject == null) {
152 result = null; 152 result = null;
153 } else { 153 } else {
154 result = typeof(anObject); 154 result = typeof(anObject);
155 155
156 if (result == "object") { 156 if (result == "object") {
157 if (anObject instanceof Array) { 157 if (anObject instanceof Array) {
158 result = 'array' 158 result = 'array'
159 } else if (anObject.constructor == Boolean) { 159 } else if (anObject.constructor == Boolean) {
160 result = 'boolean' 160 result = 'boolean'
161 } else if (anObject instanceof Date) { 161 } else if (anObject instanceof Date) {
162 result = 'date' 162 result = 'date'
163 } else if (anObject instanceof Error) { 163 } else if (anObject instanceof Error) {
164 result = 'error' 164 result = 'error'
165 } else if (anObject instanceof Function) { 165 } else if (anObject instanceof Function) {
166 result = 'function' 166 result = 'function'
167 } else if (anObject.constructor == Number) { 167 } else if (anObject.constructor == Number) {
168 result = 'number' 168 result = 'number'
169 } else if (anObject.constructor == String) { 169 } else if (anObject.constructor == String) {
170 result = 'string' 170 result = 'string'
171 } else if (anObject instanceof Object) { 171 } else if (anObject instanceof Object) {
172 result = 'object' 172 result = 'object'
173 } else { 173 } else {
174 throw Clipperz.Base.exception.UnknownType; 174 throw Clipperz.Base.exception.UnknownType;
175 } 175 }
176 } 176 }
177 } 177 }
178 178
179 return result; 179 return result;
180 }, 180 },
181 181
182 //------------------------------------------------------------------------- 182 //-------------------------------------------------------------------------
183 183
184 'escapeHTML': function(aValue) { 184 'escapeHTML': function(aValue) {
185 var result; 185 var result;
186 186
187 result = aValue; 187 result = aValue;
188 result = result.replace(/</g, "&lt;"); 188 result = result.replace(/</g, "&lt;");
189 result = result.replace(/>/g, "&gt;"); 189 result = result.replace(/>/g, "&gt;");
190 190
191 return result; 191 return result;
192 }, 192 },
193 193
194 //------------------------------------------------------------------------- 194 //-------------------------------------------------------------------------
195 195
196 'deepClone': function(anObject) { 196 'deepClone': function(anObject) {
197 var result; 197 var result;
198 198
199 result = Clipperz.Base.evalJSON(Clipperz.Base.serializeJSON(anObject)); 199 result = Clipperz.Base.evalJSON(Clipperz.Base.serializeJSON(anObject));
200 200
201 return result; 201 return result;
202 }, 202 },
203 203
204 //------------------------------------------------------------------------- 204 //-------------------------------------------------------------------------
205 205
206 'evalJSON': function(aString) { 206 'evalJSON': function(aString) {
207/* 207/*
208 var result; 208 var result;
209 209
210 //check for XSS injection 210 //check for XSS injection
211 if (/<script>/.test(aString)) { 211 if (/<script>/.test(aString)) {
212 throw "error"; 212 throw "error";
213 } 213 }
214 214
215 if (/<iframe>/.test(aString)) { 215 if (/<iframe>/.test(aString)) {
216 throw "error"; 216 throw "error";
217 } 217 }
218 218
219 result = MochiKit.Base.evalJSON(aString); 219 result = MochiKit.Base.evalJSON(aString);
220 220
221 return result; 221 return result;
222*/ 222*/
223 223
224 // return MochiKit.Base.evalJSON(aString); 224 // return MochiKit.Base.evalJSON(aString);
225 return JSON2.parse(aString); 225 return JSON2.parse(aString);
226 }, 226 },
227 227
228 'serializeJSON': function(anObject) { 228 'serializeJSON': function(anObject) {
229 // return MochiKit.Base.serializeJSON(anObject); 229 // return MochiKit.Base.serializeJSON(anObject);
230 return JSON2.stringify(anObject); 230 return JSON2.stringify(anObject);
231 }, 231 },
232 232
233 //------------------------------------------------------------------------- 233 //-------------------------------------------------------------------------
234 234
235 'sanitizeString': function(aValue) { 235 'sanitizeString': function(aValue) {
236 var result; 236 var result;
237 237
238 if (Clipperz.Base.objectType(aValue) == 'string') { 238 if (Clipperz.Base.objectType(aValue) == 'string') {
239 result = aValue; 239 result = aValue;
240 result = result.replace(/</img,"&lt;"); 240 result = result.replace(/</img,"&lt;");
241 result = result.replace(/>/img,"&gt;"); 241 result = result.replace(/>/img,"&gt;");
242 } else { 242 } else {
243 result = aValue; 243 result = aValue;
244 } 244 }
245 245
246 return result; 246 return result;
247 }, 247 },
248 248
249 'javascriptInjectionPattern': new RegExp("javascript:\/\/\"", "g"),
250
251 'sanitizeUrl': function(aValue) {
252 varresult;
253
254 if ((aValue != null) && this.javascriptInjectionPattern.test(aValue)) {
255 result = aValue.replace(this.javascriptInjectionPattern, '');
256 console.log("sanitized url", aValue, result);
257 } else {
258 result = aValue;
259 }
260
261 return result;
262 },
263
264 'sanitizeFavicon': function(aValue) {
265 varresult;
266
267 if ((aValue != null) && this.javascriptInjectionPattern.test(aValue)) {
268 result = aValue.replace(this.javascriptInjectionPattern, '');
269 console.log("sanitized favicon", aValue, result);
270 } else {
271 result = aValue;
272 }
273
274 return result;
275 },
276
249 //------------------------------------------------------------------------- 277 //-------------------------------------------------------------------------
250 278
251 'exception': { 279 'exception': {
252 'AbstractMethod': new MochiKit.Base.NamedError("Clipperz.Base.exception.AbstractMethod"), 280 'AbstractMethod': new MochiKit.Base.NamedError("Clipperz.Base.exception.AbstractMethod"),
253 'UnknownType': new MochiKit.Base.NamedError("Clipperz.Base.exception.UnknownType"), 281 'UnknownType': new MochiKit.Base.NamedError("Clipperz.Base.exception.UnknownType"),
254 'VulnerabilityIssue':new MochiKit.Base.NamedError("Clipperz.Base.exception.VulnerabilityIssue") 282 'VulnerabilityIssue':new MochiKit.Base.NamedError("Clipperz.Base.exception.VulnerabilityIssue")
255 }, 283 },
256 284
257 //------------------------------------------------------------------------- 285 //-------------------------------------------------------------------------
258 __syntaxFix__: "syntax fix" 286 __syntaxFix__: "syntax fix"
259 287
260}); 288});
261 289
262 290
263 291
264MochiKit.Base.registerComparator('Object dummy comparator', 292MochiKit.Base.registerComparator('Object dummy comparator',
265 function(a, b) { 293 function(a, b) {
266 return ((a.constructor == Object) && (b.constructor == Object)); 294 return ((a.constructor == Object) && (b.constructor == Object));
267 }, 295 },
268 function(a, b) { 296 function(a, b) {
269 var result; 297 var result;
270 var aKeys; 298 var aKeys;
271 var bKeys; 299 var bKeys;
272 300
273//MochiKit.Logging.logDebug(">>> comparator"); 301//MochiKit.Logging.logDebug(">>> comparator");
274//MochiKit.Logging.logDebug("- a: " + Clipperz.Base.serializeJSON(a)); 302//MochiKit.Logging.logDebug("- a: " + Clipperz.Base.serializeJSON(a));
275//MochiKit.Logging.logDebug("- b: " + Clipperz.Base.serializeJSON(a)); 303//MochiKit.Logging.logDebug("- b: " + Clipperz.Base.serializeJSON(a));
276 aKeys = MochiKit.Base.keys(a).sort(); 304 aKeys = MochiKit.Base.keys(a).sort();
277 bKeys = MochiKit.Base.keys(b).sort(); 305 bKeys = MochiKit.Base.keys(b).sort();
278 306
279 result = MochiKit.Base.compare(aKeys, bKeys); 307 result = MochiKit.Base.compare(aKeys, bKeys);
280//if (result != 0) { 308//if (result != 0) {
281 //MochiKit.Logging.logDebug("- comparator 'keys':"); 309 //MochiKit.Logging.logDebug("- comparator 'keys':");
282 //MochiKit.Logging.logDebug("- comparator aKeys: " + Clipperz.Base.serializeJSON(aKeys)); 310 //MochiKit.Logging.logDebug("- comparator aKeys: " + Clipperz.Base.serializeJSON(aKeys));
283 //MochiKit.Logging.logDebug("- comparator bKeys: " + Clipperz.Base.serializeJSON(bKeys)); 311 //MochiKit.Logging.logDebug("- comparator bKeys: " + Clipperz.Base.serializeJSON(bKeys));
284//} 312//}
285 if (result == 0) { 313 if (result == 0) {
286 vari, c; 314 vari, c;
287 315
288 c = aKeys.length; 316 c = aKeys.length;
289 for (i=0; (i<c) && (result == 0); i++) { 317 for (i=0; (i<c) && (result == 0); i++) {
290 result = MochiKit.Base.compare(a[aKeys[i]], b[bKeys[i]]); 318 result = MochiKit.Base.compare(a[aKeys[i]], b[bKeys[i]]);
291//if (result != 0) { 319//if (result != 0) {
292 //MochiKit.Logging.logDebug("- comparator 'values':"); 320 //MochiKit.Logging.logDebug("- comparator 'values':");
293 //MochiKit.Logging.logDebug("- comparator a[aKeys[i]]: " + Clipperz.Base.serializeJSON(a[aKeys[i]])); 321 //MochiKit.Logging.logDebug("- comparator a[aKeys[i]]: " + Clipperz.Base.serializeJSON(a[aKeys[i]]));
294 //MochiKit.Logging.logDebug("- comparator b[bKeys[i]]: " + Clipperz.Base.serializeJSON(b[bKeys[i]])); 322 //MochiKit.Logging.logDebug("- comparator b[bKeys[i]]: " + Clipperz.Base.serializeJSON(b[bKeys[i]]));
295//} 323//}
296 } 324 }
297 } 325 }
298 326
299//MochiKit.Logging.logDebug("<<< comparator - result: " + result); 327//MochiKit.Logging.logDebug("<<< comparator - result: " + result);
300 return result; 328 return result;
301 }, 329 },
302 true 330 true
303); 331);
diff --git a/frontend/beta/js/Clipperz/Crypto/PRNG.js b/frontend/beta/js/Clipperz/Crypto/PRNG.js
index b5c3f8a..6fdeca4 100644
--- a/frontend/beta/js/Clipperz/Crypto/PRNG.js
+++ b/frontend/beta/js/Clipperz/Crypto/PRNG.js
@@ -8,842 +8,798 @@ refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { 24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; 25 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
26} 26}
27 27
28try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) { 28try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) {
29 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!"; 29 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!";
30} 30}
31 31
32try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) { 32try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) {
33 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!"; 33 throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!";
34} 34}
35 35
36if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; } 36if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; }
37 37
38//############################################################################# 38//#############################################################################
39 39
40Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) { 40Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) {
41 args = args || {}; 41 args = args || {};
42 //MochiKit.Base.bindMethods(this); 42 //MochiKit.Base.bindMethods(this);
43 43
44 this._stack = new Clipperz.ByteArray(); 44 this._stack = new Clipperz.ByteArray();
45 this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256; 45 this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256;
46 return this; 46 return this;
47} 47}
48 48
49Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, { 49Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, {
50 50
51 'toString': function() { 51 'toString': function() {
52 return "Clipperz.Crypto.PRNG.EntropyAccumulator"; 52 return "Clipperz.Crypto.PRNG.EntropyAccumulator";
53 }, 53 },
54 54
55 //------------------------------------------------------------------------- 55 //-------------------------------------------------------------------------
56 56
57 'stack': function() { 57 'stack': function() {
58 return this._stack; 58 return this._stack;
59 }, 59 },
60 60
61 'setStack': function(aValue) { 61 'setStack': function(aValue) {
62 this._stack = aValue; 62 this._stack = aValue;
63 }, 63 },
64 64
65 'resetStack': function() { 65 'resetStack': function() {
66 this.stack().reset(); 66 this.stack().reset();
67 }, 67 },
68 68
69 'maxStackLengthBeforeHashing': function() { 69 'maxStackLengthBeforeHashing': function() {
70 return this._maxStackLengthBeforeHashing; 70 return this._maxStackLengthBeforeHashing;
71 }, 71 },
72 72
73 //------------------------------------------------------------------------- 73 //-------------------------------------------------------------------------
74 74
75 'addRandomByte': function(aValue) { 75 'addRandomByte': function(aValue) {
76 this.stack().appendByte(aValue); 76 this.stack().appendByte(aValue);
77 77
78 if (this.stack().length() > this.maxStackLengthBeforeHashing()) { 78 if (this.stack().length() > this.maxStackLengthBeforeHashing()) {
79 this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack())); 79 this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack()));
80 } 80 }
81 }, 81 },
82 82
83 //------------------------------------------------------------------------- 83 //-------------------------------------------------------------------------
84 __syntaxFix__: "syntax fix" 84 __syntaxFix__: "syntax fix"
85}); 85});
86 86
87//############################################################################# 87//#############################################################################
88 88
89Clipperz.Crypto.PRNG.RandomnessSource = function(args) { 89Clipperz.Crypto.PRNG.RandomnessSource = function(args) {
90 args = args || {}; 90 args = args || {};
91 MochiKit.Base.bindMethods(this); 91 MochiKit.Base.bindMethods(this);
92 92
93 this._generator = args.generator || null; 93 this._generator = args.generator || null;
94 this._sourceId = args.sourceId || null; 94 this._sourceId = args.sourceId || null;
95 this._boostMode = args.boostMode || false; 95 this._boostMode = args.boostMode || false;
96 96
97 this._nextPoolIndex = 0; 97 this._nextPoolIndex = 0;
98 98
99 return this; 99 return this;
100} 100}
101 101
102Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, { 102Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, {
103 103
104 'generator': function() { 104 'generator': function() {
105 return this._generator; 105 return this._generator;
106 }, 106 },
107 107
108 'setGenerator': function(aValue) { 108 'setGenerator': function(aValue) {
109 this._generator = aValue; 109 this._generator = aValue;
110 }, 110 },
111 111
112 //------------------------------------------------------------------------- 112 //-------------------------------------------------------------------------
113 113
114 'boostMode': function() { 114 'boostMode': function() {
115 return this._boostMode; 115 return this._boostMode;
116 }, 116 },
117 117
118 'setBoostMode': function(aValue) { 118 'setBoostMode': function(aValue) {
119 this._boostMode = aValue; 119 this._boostMode = aValue;
120 }, 120 },
121 121
122 //------------------------------------------------------------------------- 122 //-------------------------------------------------------------------------
123 123
124 'sourceId': function() { 124 'sourceId': function() {
125 return this._sourceId; 125 return this._sourceId;
126 }, 126 },
127 127
128 'setSourceId': function(aValue) { 128 'setSourceId': function(aValue) {
129 this._sourceId = aValue; 129 this._sourceId = aValue;
130 }, 130 },
131 131
132 //------------------------------------------------------------------------- 132 //-------------------------------------------------------------------------
133 133
134 'nextPoolIndex': function() { 134 'nextPoolIndex': function() {
135 return this._nextPoolIndex; 135 return this._nextPoolIndex;
136 }, 136 },
137 137
138 'incrementNextPoolIndex': function() { 138 'incrementNextPoolIndex': function() {
139 this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators()); 139 this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators());
140 }, 140 },
141 141
142 //------------------------------------------------------------------------- 142 //-------------------------------------------------------------------------
143 143
144 'updateGeneratorWithValue': function(aRandomValue) { 144 'updateGeneratorWithValue': function(aRandomValue) {
145 if (this.generator() != null) { 145 if (this.generator() != null) {
146 this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue); 146 this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue);
147 this.incrementNextPoolIndex(); 147 this.incrementNextPoolIndex();
148 } 148 }
149 }, 149 },
150 150
151 //------------------------------------------------------------------------- 151 //-------------------------------------------------------------------------
152 __syntaxFix__: "syntax fix" 152 __syntaxFix__: "syntax fix"
153}); 153});
154 154
155//############################################################################# 155//#############################################################################
156 156
157Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) { 157Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) {
158 args = args || {}; 158 args = args || {};
159 //MochiKit.Base.bindMethods(this); 159 //MochiKit.Base.bindMethods(this);
160 160
161 this._intervalTime = args.intervalTime || 1000; 161 this._intervalTime = args.intervalTime || 1000;
162 162
163 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); 163 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
164 164
165 this.collectEntropy(); 165 this.collectEntropy();
166 return this; 166 return this;
167} 167}
168 168
169Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 169Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
170 170
171 'intervalTime': function() { 171 'intervalTime': function() {
172 return this._intervalTime; 172 return this._intervalTime;
173 }, 173 },
174 174
175 //------------------------------------------------------------------------- 175 //-------------------------------------------------------------------------
176 176
177 'collectEntropy': function() { 177 'collectEntropy': function() {
178 varnow; 178 varnow;
179 varentropyByte; 179 varentropyByte;
180 var intervalTime; 180 var intervalTime;
181 now = new Date(); 181 now = new Date();
182 entropyByte = (now.getTime() & 0xff); 182 entropyByte = (now.getTime() & 0xff);
183 183
184 intervalTime = this.intervalTime(); 184 intervalTime = this.intervalTime();
185 if (this.boostMode() == true) { 185 if (this.boostMode() == true) {
186 intervalTime = intervalTime / 9; 186 intervalTime = intervalTime / 9;
187 } 187 }
188 188
189 this.updateGeneratorWithValue(entropyByte); 189 this.updateGeneratorWithValue(entropyByte);
190 setTimeout(this.collectEntropy, intervalTime); 190 setTimeout(this.collectEntropy, intervalTime);
191 }, 191 },
192 192
193 //------------------------------------------------------------------------- 193 //-------------------------------------------------------------------------
194 194
195 'numberOfRandomBits': function() { 195 'numberOfRandomBits': function() {
196 return 5; 196 return 5;
197 }, 197 },
198 198
199 //------------------------------------------------------------------------- 199 //-------------------------------------------------------------------------
200
201 'pollingFrequency': function() {
202 return 10;
203 },
204
205 //-------------------------------------------------------------------------
206 __syntaxFix__: "syntax fix" 200 __syntaxFix__: "syntax fix"
207}); 201});
208 202
209//***************************************************************************** 203//*****************************************************************************
210 204
211Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) { 205Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) {
212 args = args || {}; 206 args = args || {};
213 207
214 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args); 208 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
215 209
216 this._numberOfBitsToCollectAtEachEvent = 4; 210 this._numberOfBitsToCollectAtEachEvent = 4;
217 this._randomBitsCollector = 0; 211 this._randomBitsCollector = 0;
218 this._numberOfRandomBitsCollected = 0; 212 this._numberOfRandomBitsCollected = 0;
219 213
220 MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy'); 214 MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy');
221 215
222 return this; 216 return this;
223} 217}
224 218
225Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 219Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
226 220
227 //------------------------------------------------------------------------- 221 //-------------------------------------------------------------------------
228 222
229 'numberOfBitsToCollectAtEachEvent': function() { 223 'numberOfBitsToCollectAtEachEvent': function() {
230 return this._numberOfBitsToCollectAtEachEvent; 224 return this._numberOfBitsToCollectAtEachEvent;
231 }, 225 },
232 226
233 //------------------------------------------------------------------------- 227 //-------------------------------------------------------------------------
234 228
235 'randomBitsCollector': function() { 229 'randomBitsCollector': function() {
236 return this._randomBitsCollector; 230 return this._randomBitsCollector;
237 }, 231 },
238 232
239 'setRandomBitsCollector': function(aValue) { 233 'setRandomBitsCollector': function(aValue) {
240 this._randomBitsCollector = aValue; 234 this._randomBitsCollector = aValue;
241 }, 235 },
242 236
243 'appendRandomBitsToRandomBitsCollector': function(aValue) { 237 'appendRandomBitsToRandomBitsCollector': function(aValue) {
244 var collectedBits; 238 var collectedBits;
245 var numberOfRandomBitsCollected; 239 var numberOfRandomBitsCollected;
246 240
247 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected(); 241 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
248 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected); 242 collectedBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
249 this.setRandomBitsCollector(collectetBits); 243 this.setRandomBitsCollector(collectedBits);
250 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent(); 244 numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent();
251 245
252 if (numberOfRandomBitsCollected == 8) { 246 if (numberOfRandomBitsCollected == 8) {
253 this.updateGeneratorWithValue(collectetBits); 247 this.updateGeneratorWithValue(collectedBits);
254 numberOfRandomBitsCollected = 0; 248 numberOfRandomBitsCollected = 0;
255 this.setRandomBitsCollector(0); 249 this.setRandomBitsCollector(0);
256 } 250 }
257 251
258 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected) 252 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
259 }, 253 },
260 254
261 //------------------------------------------------------------------------- 255 //-------------------------------------------------------------------------
262 256
263 'numberOfRandomBitsCollected': function() { 257 'numberOfRandomBitsCollected': function() {
264 return this._numberOfRandomBitsCollected; 258 return this._numberOfRandomBitsCollected;
265 }, 259 },
266 260
267 'setNumberOfRandomBitsCollected': function(aValue) { 261 'setNumberOfRandomBitsCollected': function(aValue) {
268 this._numberOfRandomBitsCollected = aValue; 262 this._numberOfRandomBitsCollected = aValue;
269 }, 263 },
270 264
271 //------------------------------------------------------------------------- 265 //-------------------------------------------------------------------------
272 266
273 'collectEntropy': function(anEvent) { 267 'collectEntropy': function(anEvent) {
274 var mouseLocation; 268 var mouseLocation;
275 var randomBit; 269 var randomBit;
276 var mask; 270 var mask;
277 271
278 mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent()); 272 mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent());
279 273
280 mouseLocation = anEvent.mouse().client; 274 mouseLocation = anEvent.mouse().client;
281 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask); 275 randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask);
282 this.appendRandomBitsToRandomBitsCollector(randomBit) 276 this.appendRandomBitsToRandomBitsCollector(randomBit)
283 }, 277 },
284 278
285 //------------------------------------------------------------------------- 279 //-------------------------------------------------------------------------
286 280
287 'numberOfRandomBits': function() { 281 'numberOfRandomBits': function() {
288 return 1; 282 return 1;
289 }, 283 },
290 284
291 //------------------------------------------------------------------------- 285 //-------------------------------------------------------------------------
292
293 'pollingFrequency': function() {
294 return 10;
295 },
296
297 //-------------------------------------------------------------------------
298 __syntaxFix__: "syntax fix" 286 __syntaxFix__: "syntax fix"
299}); 287});
300 288
301//***************************************************************************** 289//*****************************************************************************
302 290
303Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) { 291Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource = function(args) {
304 args = args || {}; 292 args = args || {};
305 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
306 293
307 this._randomBitsCollector = 0; 294 this._intervalTime = args.intervalTime || 1000;
308 this._numberOfRandomBitsCollected = 0; 295 this._browserCrypto = args.browserCrypto;
309 296
310 MochiKit.Signal.connect(document, 'onkeypress', this, 'collectEntropy'); 297 Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
311 298
299 this.collectEntropy();
312 return this; 300 return this;
313} 301}
314 302
315Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, { 303Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
316
317 //-------------------------------------------------------------------------
318
319 'randomBitsCollector': function() {
320 return this._randomBitsCollector;
321 },
322 304
323 'setRandomBitsCollector': function(aValue) { 305 'intervalTime': function() {
324 this._randomBitsCollector = aValue; 306 return this._intervalTime;
325 }, 307 },
326 308
327 'appendRandomBitToRandomBitsCollector': function(aValue) { 309 'browserCrypto': function () {
328 var collectedBits; 310 return this._browserCrypto;
329 var numberOfRandomBitsCollected;
330
331 numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
332 collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
333 this.setRandomBitsCollector(collectetBits);
334 numberOfRandomBitsCollected ++;
335
336 if (numberOfRandomBitsCollected == 8) {
337 this.updateGeneratorWithValue(collectetBits);
338 numberOfRandomBitsCollected = 0;
339 this.setRandomBitsCollector(0);
340 }
341
342 this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
343 }, 311 },
344 312
345 //------------------------------------------------------------------------- 313 //-------------------------------------------------------------------------
346 314
347 'numberOfRandomBitsCollected': function() { 315 'collectEntropy': function() {
348 return this._numberOfRandomBitsCollected; 316 varbytesToCollect;
349 },
350
351 'setNumberOfRandomBitsCollected': function(aValue) {
352 this._numberOfRandomBitsCollected = aValue;
353 },
354 317
355 //------------------------------------------------------------------------- 318 if (this.boostMode() == true) {
319 bytesToCollect = 64;
320 } else {
321 bytesToCollect = 8;
322 }
356 323
357 'collectEntropy': function(anEvent) { 324 var randomValuesArray = new Uint8Array(bytesToCollect);
358/* 325 this.browserCrypto().getRandomValues(randomValuesArray);
359 var mouseLocation; 326 for (var i = 0; i < randomValuesArray.length; i++) {
360 var randomBit; 327 this.updateGeneratorWithValue(randomValuesArray[i]);
361 328 }
362 mouseLocation = anEvent.mouse().client;
363
364 randomBit = ((mouseLocation.x ^ mouseLocation.y) & 0x1);
365 this.appendRandomBitToRandomBitsCollector(randomBit);
366*/
367 },
368
369 //-------------------------------------------------------------------------
370 329
371 'numberOfRandomBits': function() { 330 setTimeout(this.collectEntropy, this.intervalTime());
372 return 1;
373 }, 331 },
374 332
375 //------------------------------------------------------------------------- 333 //-------------------------------------------------------------------------
376
377 'pollingFrequency': function() {
378 return 10;
379 },
380
381 //-------------------------------------------------------------------------
382 __syntaxFix__: "syntax fix" 334 __syntaxFix__: "syntax fix"
383}); 335});
384 336
385//############################################################################# 337//#############################################################################
386 338
387Clipperz.Crypto.PRNG.Fortuna = function(args) { 339Clipperz.Crypto.PRNG.Fortuna = function(args) {
388 vari,c; 340 vari,c;
389 341
390 args = args || {}; 342 args = args || {};
391 343
392 this._key = args.seed || null; 344 this._key = args.seed || null;
393 if (this._key == null) { 345 if (this._key == null) {
394 this._counter = 0; 346 this._counter = 0;
395 this._key = new Clipperz.ByteArray(); 347 this._key = new Clipperz.ByteArray();
396 } else { 348 } else {
397 this._counter = 1; 349 this._counter = 1;
398 } 350 }
399 351
400 this._aesKey = null; 352 this._aesKey = null;
401 353
402 this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64; 354 this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64;
403 this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32; 355 this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32;
404 356
405 this._accumulators = []; 357 this._accumulators = [];
406 c = this.numberOfEntropyAccumulators(); 358 c = this.numberOfEntropyAccumulators();
407 for (i=0; i<c; i++) { 359 for (i=0; i<c; i++) {
408 this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator()); 360 this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator());
409 } 361 }
410 362
411 this._randomnessSources = []; 363 this._randomnessSources = [];
412 this._reseedCounter = 0; 364 this._reseedCounter = 0;
413 365
414 return this; 366 return this;
415} 367}
416 368
417Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, { 369Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, {
418 370
419 'toString': function() { 371 'toString': function() {
420 return "Clipperz.Crypto.PRNG.Fortuna"; 372 return "Clipperz.Crypto.PRNG.Fortuna";
421 }, 373 },
422 374
423 //------------------------------------------------------------------------- 375 //-------------------------------------------------------------------------
424 376
425 'key': function() { 377 'key': function() {
426 return this._key; 378 return this._key;
427 }, 379 },
428 380
429 'setKey': function(aValue) { 381 'setKey': function(aValue) {
430 this._key = aValue; 382 this._key = aValue;
431 this._aesKey = null; 383 this._aesKey = null;
432 }, 384 },
433 385
434 'aesKey': function() { 386 'aesKey': function() {
435 if (this._aesKey == null) { 387 if (this._aesKey == null) {
436 this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()}); 388 this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()});
437 } 389 }
438 390
439 return this._aesKey; 391 return this._aesKey;
440 }, 392 },
441 393
442 'accumulators': function() { 394 'accumulators': function() {
443 return this._accumulators; 395 return this._accumulators;
444 }, 396 },
445 397
446 'firstPoolReseedLevel': function() { 398 'firstPoolReseedLevel': function() {
447 return this._firstPoolReseedLevel; 399 return this._firstPoolReseedLevel;
448 }, 400 },
449 401
450 //------------------------------------------------------------------------- 402 //-------------------------------------------------------------------------
451 403
452 'reseedCounter': function() { 404 'reseedCounter': function() {
453 return this._reseedCounter; 405 return this._reseedCounter;
454 }, 406 },
455 407
456 'incrementReseedCounter': function() { 408 'incrementReseedCounter': function() {
457 this._reseedCounter = this._reseedCounter +1; 409 this._reseedCounter = this._reseedCounter +1;
458 }, 410 },
459 411
460 //------------------------------------------------------------------------- 412 //-------------------------------------------------------------------------
461 413
462 'reseed': function() { 414 'reseed': function() {
463 varnewKeySeed; 415 varnewKeySeed;
464 var reseedCounter; 416 var reseedCounter;
465 varreseedCounterMask; 417 varreseedCounterMask;
466 var i, c; 418 var i, c;
467 419
468 newKeySeed = this.key(); 420 newKeySeed = this.key();
469 this.incrementReseedCounter(); 421 this.incrementReseedCounter();
470 reseedCounter = this.reseedCounter(); 422 reseedCounter = this.reseedCounter();
471 423
472 c = this.numberOfEntropyAccumulators(); 424 c = this.numberOfEntropyAccumulators();
473 reseedCounterMask = 0xffffffff >>> (32 - c); 425 reseedCounterMask = 0xffffffff >>> (32 - c);
474 for (i=0; i<c; i++) { 426 for (i=0; i<c; i++) {
475 if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) { 427 if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) {
476 newKeySeed.appendBlock(this.accumulators()[i].stack()); 428 newKeySeed.appendBlock(this.accumulators()[i].stack());
477 this.accumulators()[i].resetStack(); 429 this.accumulators()[i].resetStack();
478 } 430 }
479 } 431 }
480 432
481 if (reseedCounter == 1) { 433 if (reseedCounter == 1) {
482 c = this.randomnessSources().length; 434 c = this.randomnessSources().length;
483 for (i=0; i<c; i++) { 435 for (i=0; i<c; i++) {
484 this.randomnessSources()[i].setBoostMode(false); 436 this.randomnessSources()[i].setBoostMode(false);
485 } 437 }
486 } 438 }
487 439
488 this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed)); 440 this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed));
489 if (reseedCounter == 1) { 441 if (reseedCounter == 1) {
490MochiKit.Logging.logDebug("### PRNG.readyToGenerateRandomBytes"); 442MochiKit.Logging.logDebug("### PRNG.readyToGenerateRandomBytes");
491 MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes'); 443 MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes');
492 } 444 }
493 MochiKit.Signal.signal(this, 'reseeded'); 445 MochiKit.Signal.signal(this, 'reseeded');
494 }, 446 },
495 447
496 //------------------------------------------------------------------------- 448 //-------------------------------------------------------------------------
497 449
498 'isReadyToGenerateRandomValues': function() { 450 'isReadyToGenerateRandomValues': function() {
499 return this.reseedCounter() != 0; 451 return this.reseedCounter() != 0;
500 }, 452 },
501 453
502 //------------------------------------------------------------------------- 454 //-------------------------------------------------------------------------
503 455
504 'entropyLevel': function() { 456 'entropyLevel': function() {
505 return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel()); 457 return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel());
506 }, 458 },
507 459
508 //------------------------------------------------------------------------- 460 //-------------------------------------------------------------------------
509 461
510 'counter': function() { 462 'counter': function() {
511 return this._counter; 463 return this._counter;
512 }, 464 },
513 465
514 'incrementCounter': function() { 466 'incrementCounter': function() {
515 this._counter += 1; 467 this._counter += 1;
516 }, 468 },
517 469
518 'counterBlock': function() { 470 'counterBlock': function() {
519 var result; 471 var result;
520 472
521 result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0); 473 result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0);
522 474
523 return result; 475 return result;
524 }, 476 },
525 477
526 //------------------------------------------------------------------------- 478 //-------------------------------------------------------------------------
527 479
528 'getRandomBlock': function() { 480 'getRandomBlock': function() {
529 var result; 481 var result;
530 482
531 result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues())); 483 result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues()));
532 this.incrementCounter(); 484 this.incrementCounter();
533 485
534 return result; 486 return result;
535 }, 487 },
536 488
537 //------------------------------------------------------------------------- 489 //-------------------------------------------------------------------------
538 490
539 'getRandomBytes': function(aSize) { 491 'getRandomBytes': function(aSize) {
540 var result; 492 var result;
541 493
542 if (this.isReadyToGenerateRandomValues()) { 494 if (this.isReadyToGenerateRandomValues()) {
543 var i,c; 495 var i,c;
544 var newKey; 496 var newKey;
545 497
546 result = new Clipperz.ByteArray(); 498 result = new Clipperz.ByteArray();
547 499
548 c = Math.ceil(aSize / (128 / 8)); 500 c = Math.ceil(aSize / (128 / 8));
549 for (i=0; i<c; i++) { 501 for (i=0; i<c; i++) {
550 result.appendBlock(this.getRandomBlock()); 502 result.appendBlock(this.getRandomBlock());
551 } 503 }
552 504
553 if (result.length() != aSize) { 505 if (result.length() != aSize) {
554 result = result.split(0, aSize); 506 result = result.split(0, aSize);
555 } 507 }
556 508
557 newKey = this.getRandomBlock().appendBlock(this.getRandomBlock()); 509 newKey = this.getRandomBlock().appendBlock(this.getRandomBlock());
558 this.setKey(newKey); 510 this.setKey(newKey);
559 } else { 511 } else {
560MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!"); 512MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
561 throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy; 513 throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy;
562 } 514 }
563 515
564 return result; 516 return result;
565 }, 517 },
566 518
567 //------------------------------------------------------------------------- 519 //-------------------------------------------------------------------------
568 520
569 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) { 521 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) {
570 varselectedAccumulator; 522 varselectedAccumulator;
571 523
572 selectedAccumulator = this.accumulators()[aPoolId]; 524 selectedAccumulator = this.accumulators()[aPoolId];
573 selectedAccumulator.addRandomByte(aRandomValue); 525 selectedAccumulator.addRandomByte(aRandomValue);
574 526
575 if (aPoolId == 0) { 527 if (aPoolId == 0) {
576 MochiKit.Signal.signal(this, 'addedRandomByte') 528 MochiKit.Signal.signal(this, 'addedRandomByte')
577 if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) { 529 if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) {
578 this.reseed(); 530 this.reseed();
579 } 531 }
580 } 532 }
581 }, 533 },
582 534
583 //------------------------------------------------------------------------- 535 //-------------------------------------------------------------------------
584 536
585 'numberOfEntropyAccumulators': function() { 537 'numberOfEntropyAccumulators': function() {
586 return this._numberOfEntropyAccumulators; 538 return this._numberOfEntropyAccumulators;
587 }, 539 },
588 540
589 //------------------------------------------------------------------------- 541 //-------------------------------------------------------------------------
590 542
591 'randomnessSources': function() { 543 'randomnessSources': function() {
592 return this._randomnessSources; 544 return this._randomnessSources;
593 }, 545 },
594 546
595 'addRandomnessSource': function(aRandomnessSource) { 547 'addRandomnessSource': function(aRandomnessSource) {
596 aRandomnessSource.setGenerator(this); 548 aRandomnessSource.setGenerator(this);
597 aRandomnessSource.setSourceId(this.randomnessSources().length); 549 aRandomnessSource.setSourceId(this.randomnessSources().length);
598 this.randomnessSources().push(aRandomnessSource); 550 this.randomnessSources().push(aRandomnessSource);
599 551
600 if (this.isReadyToGenerateRandomValues() == false) { 552 if (this.isReadyToGenerateRandomValues() == false) {
601 aRandomnessSource.setBoostMode(true); 553 aRandomnessSource.setBoostMode(true);
602 } 554 }
603 }, 555 },
604 556
605 //------------------------------------------------------------------------- 557 //-------------------------------------------------------------------------
606 558
607 'deferredEntropyCollection': function(aValue) { 559 'deferredEntropyCollection': function(aValue) {
608 var result; 560 var result;
609 561
610//MochiKit.Logging.logDebug(">>> PRNG.deferredEntropyCollection");
611 562
612 if (this.isReadyToGenerateRandomValues()) { 563 if (this.isReadyToGenerateRandomValues()) {
613//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 1");
614 result = aValue; 564 result = aValue;
615 } else { 565 } else {
616//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 2");
617 var deferredResult; 566 var deferredResult;
618 567
619 Clipperz.NotificationCenter.notify(this, 'updatedProgressState', 'collectingEntropy', true); 568 Clipperz.NotificationCenter.notify(this, 'updatedProgressState', 'collectingEntropy', true);
620 569
621 deferredResult = new MochiKit.Async.Deferred(); 570 deferredResult = new MochiKit.Async.Deferred();
622 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.1 - PRNG.deferredEntropyCollection - 1: " + res); return res;});
623 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue)); 571 deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue));
624 // deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.2 - PRNG.deferredEntropyCollection - 2: " + res); return res;});
625 MochiKit.Signal.connect(this, 572 MochiKit.Signal.connect(this,
626 'readyToGenerateRandomBytes', 573 'readyToGenerateRandomBytes',
627 deferredResult, 574 deferredResult,
628 'callback'); 575 'callback');
629 576
630 result = deferredResult; 577 result = deferredResult;
631 } 578 }
632//MochiKit.Logging.logDebug("<<< PRNG.deferredEntropyCollection - result: " + result);
633 579
634 return result; 580 return result;
635 }, 581 },
636 582
637 //------------------------------------------------------------------------- 583 //-------------------------------------------------------------------------
638 584
639 'fastEntropyAccumulationForTestingPurpose': function() { 585 'fastEntropyAccumulationForTestingPurpose': function() {
640 while (! this.isReadyToGenerateRandomValues()) { 586 while (! this.isReadyToGenerateRandomValues()) {
641 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256)); 587 this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256));
642 } 588 }
643 }, 589 },
644 590
645 //------------------------------------------------------------------------- 591 //-------------------------------------------------------------------------
646 592/*
647 'dump': function(appendToDoc) { 593 'dump': function(appendToDoc) {
648 var tbl; 594 var tbl;
649 var i,c; 595 var i,c;
650 596
651 tbl = document.createElement("table"); 597 tbl = document.createElement("table");
652 tbl.border = 0; 598 tbl.border = 0;
653 with (tbl.style) { 599 with (tbl.style) {
654 border = "1px solid lightgrey"; 600 border = "1px solid lightgrey";
655 fontFamily = 'Helvetica, Arial, sans-serif'; 601 fontFamily = 'Helvetica, Arial, sans-serif';
656 fontSize = '8pt'; 602 fontSize = '8pt';
657 //borderCollapse = "collapse"; 603 //borderCollapse = "collapse";
658 } 604 }
659 var hdr = tbl.createTHead(); 605 var hdr = tbl.createTHead();
660 var hdrtr = hdr.insertRow(0); 606 var hdrtr = hdr.insertRow(0);
661 // document.createElement("tr"); 607 // document.createElement("tr");
662 { 608 {
663 var ntd; 609 var ntd;
664 610
665 ntd = hdrtr.insertCell(0); 611 ntd = hdrtr.insertCell(0);
666 ntd.style.borderBottom = "1px solid lightgrey"; 612 ntd.style.borderBottom = "1px solid lightgrey";
667 ntd.style.borderRight = "1px solid lightgrey"; 613 ntd.style.borderRight = "1px solid lightgrey";
668 ntd.appendChild(document.createTextNode("#")); 614 ntd.appendChild(document.createTextNode("#"));
669 615
670 ntd = hdrtr.insertCell(1); 616 ntd = hdrtr.insertCell(1);
671 ntd.style.borderBottom = "1px solid lightgrey"; 617 ntd.style.borderBottom = "1px solid lightgrey";
672 ntd.style.borderRight = "1px solid lightgrey"; 618 ntd.style.borderRight = "1px solid lightgrey";
673 ntd.appendChild(document.createTextNode("s")); 619 ntd.appendChild(document.createTextNode("s"));
674 620
675 ntd = hdrtr.insertCell(2); 621 ntd = hdrtr.insertCell(2);
676 ntd.colSpan = this.firstPoolReseedLevel(); 622 ntd.colSpan = this.firstPoolReseedLevel();
677 ntd.style.borderBottom = "1px solid lightgrey"; 623 ntd.style.borderBottom = "1px solid lightgrey";
678 ntd.style.borderRight = "1px solid lightgrey"; 624 ntd.style.borderRight = "1px solid lightgrey";
679 ntd.appendChild(document.createTextNode("base values")); 625 ntd.appendChild(document.createTextNode("base values"));
680 626
681 ntd = hdrtr.insertCell(3); 627 ntd = hdrtr.insertCell(3);
682 ntd.colSpan = 20; 628 ntd.colSpan = 20;
683 ntd.style.borderBottom = "1px solid lightgrey"; 629 ntd.style.borderBottom = "1px solid lightgrey";
684 ntd.appendChild(document.createTextNode("extra values")); 630 ntd.appendChild(document.createTextNode("extra values"));
685 631
686 } 632 }
687 633
688 c = this.accumulators().length; 634 c = this.accumulators().length;
689 for (i=0; i<c ; i++) { 635 for (i=0; i<c ; i++) {
690 varcurrentAccumulator; 636 varcurrentAccumulator;
691 var bdytr; 637 var bdytr;
692 var bdytd; 638 var bdytd;
693 var ii, cc; 639 var ii, cc;
694 640
695 currentAccumulator = this.accumulators()[i] 641 currentAccumulator = this.accumulators()[i]
696 642
697 bdytr = tbl.insertRow(true); 643 bdytr = tbl.insertRow(true);
698 644
699 bdytd = bdytr.insertCell(0); 645 bdytd = bdytr.insertCell(0);
700 bdytd.style.borderRight = "1px solid lightgrey"; 646 bdytd.style.borderRight = "1px solid lightgrey";
701 bdytd.style.color = "lightgrey"; 647 bdytd.style.color = "lightgrey";
702 bdytd.appendChild(document.createTextNode("" + i)); 648 bdytd.appendChild(document.createTextNode("" + i));
703 649
704 bdytd = bdytr.insertCell(1); 650 bdytd = bdytr.insertCell(1);
705 bdytd.style.borderRight = "1px solid lightgrey"; 651 bdytd.style.borderRight = "1px solid lightgrey";
706 bdytd.style.color = "gray"; 652 bdytd.style.color = "gray";
707 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length())); 653 bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length()));
708 654
709 655
710 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel()); 656 cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel());
711 for (ii=0; ii<cc; ii++) { 657 for (ii=0; ii<cc; ii++) {
712 var cellText; 658 var cellText;
713 659
714 bdytd = bdytr.insertCell(ii + 2); 660 bdytd = bdytr.insertCell(ii + 2);
715 661
716 if (ii < currentAccumulator.stack().length()) { 662 if (ii < currentAccumulator.stack().length()) {
717 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii)); 663 cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii));
718 } else { 664 } else {
719 cellText = "_"; 665 cellText = "_";
720 } 666 }
721 667
722 if (ii == (this.firstPoolReseedLevel() - 1)) { 668 if (ii == (this.firstPoolReseedLevel() - 1)) {
723 bdytd.style.borderRight = "1px solid lightgrey"; 669 bdytd.style.borderRight = "1px solid lightgrey";
724 } 670 }
725 671
726 bdytd.appendChild(document.createTextNode(cellText)); 672 bdytd.appendChild(document.createTextNode(cellText));
727 } 673 }
728 674
729 } 675 }
730 676
731 677
732 if (appendToDoc) { 678 if (appendToDoc) {
733 var ne = document.createElement("div"); 679 var ne = document.createElement("div");
734 ne.id = "entropyGeneratorStatus"; 680 ne.id = "entropyGeneratorStatus";
735 with (ne.style) { 681 with (ne.style) {
736 fontFamily = "Courier New, monospace"; 682 fontFamily = "Courier New, monospace";
737 fontSize = "12px"; 683 fontSize = "12px";
738 lineHeight = "16px"; 684 lineHeight = "16px";
739 borderTop = "1px solid black"; 685 borderTop = "1px solid black";
740 padding = "10px"; 686 padding = "10px";
741 } 687 }
742 if (document.getElementById(ne.id)) { 688 if (document.getElementById(ne.id)) {
743 MochiKit.DOM.swapDOM(ne.id, ne); 689 MochiKit.DOM.swapDOM(ne.id, ne);
744 } else { 690 } else {
745 document.body.appendChild(ne); 691 document.body.appendChild(ne);
746 } 692 }
747 ne.appendChild(tbl); 693 ne.appendChild(tbl);
748 } 694 }
749 695
750 return tbl; 696 return tbl;
751 }, 697 },
752 698*/
753 //----------------------------------------------------------------------------- 699 //-----------------------------------------------------------------------------
754 __syntaxFix__: "syntax fix" 700 __syntaxFix__: "syntax fix"
755}); 701});
756 702
757//############################################################################# 703//#############################################################################
758 704
759Clipperz.Crypto.PRNG.Random = function(args) { 705Clipperz.Crypto.PRNG.Random = function(args) {
760 args = args || {}; 706 args = args || {};
761 //MochiKit.Base.bindMethods(this); 707 //MochiKit.Base.bindMethods(this);
762 708
763 return this; 709 return this;
764} 710}
765 711
766Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, { 712Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
767 713
768 'toString': function() { 714 'toString': function() {
769 return "Clipperz.Crypto.PRNG.Random"; 715 return "Clipperz.Crypto.PRNG.Random";
770 }, 716 },
771 717
772 //------------------------------------------------------------------------- 718 //-------------------------------------------------------------------------
773 719
774 'getRandomBytes': function(aSize) { 720 'getRandomBytes': function(aSize) {
775//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes"); 721//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes");
776 varresult; 722 varresult;
777 var i,c; 723 var i,c;
778 724
779 result = new Clipperz.ByteArray() 725 result = new Clipperz.ByteArray()
780 c = aSize || 1; 726 c = aSize || 1;
781 for (i=0; i<c; i++) { 727 for (i=0; i<c; i++) {
782 result.appendByte((Math.random()*255) & 0xff); 728 result.appendByte((Math.random()*255) & 0xff);
783 } 729 }
784 730
785//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes"); 731//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes");
786 return result; 732 return result;
787 }, 733 },
788 734
789 //------------------------------------------------------------------------- 735 //-------------------------------------------------------------------------
790 __syntaxFix__: "syntax fix" 736 __syntaxFix__: "syntax fix"
791}); 737});
792 738
793//############################################################################# 739//#############################################################################
794 740
795_clipperz_crypt_prng_defaultPRNG = null; 741_clipperz_crypt_prng_defaultPRNG = null;
796 742
797Clipperz.Crypto.PRNG.defaultRandomGenerator = function() { 743Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
798 if (_clipperz_crypt_prng_defaultPRNG == null) { 744 if (_clipperz_crypt_prng_defaultPRNG == null) {
799 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna(); 745 _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna();
800 746
801 //............................................................. 747 //.............................................................
802 // 748 //
803 // TimeRandomnessSource 749 // TimeRandomnessSource
804 // 750 //
805 //............................................................. 751 //.............................................................
806 { 752 {
807 var newRandomnessSource; 753 var newRandomnessSource;
808 754
809 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111}); 755 newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111});
810 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 756 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
811 } 757 }
812 758
813 //............................................................. 759 //.............................................................
814 // 760 //
815 // MouseRandomnessSource 761 // MouseRandomnessSource
816 // 762 //
817 //............................................................. 763 //.............................................................
818 { 764 {
819 varnewRandomnessSource; 765 varnewRandomnessSource;
820 766
821 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource(); 767 newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource();
822 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 768 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
823 } 769 }
824 770
825 //............................................................. 771 //.............................................................
826 // 772 //
827 // KeyboardRandomnessSource 773 // CryptoRandomRandomnessSource
828 // 774 //
829 //............................................................. 775 //.............................................................
830 { 776 {
831 varnewRandomnessSource; 777 varnewRandomnessSource;
778 varbrowserCrypto;
832 779
833 newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource(); 780 if (window.crypto && window.crypto.getRandomValues) {
834 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource); 781 browserCrypto = window.crypto;
782 } else if (window.msCrypto && window.msCrypto.getRandomValues) {
783 browserCrypto = window.msCrypto;
784 } else {
785 browserCrypto = null;
786 }
787
788 if (browserCrypto != null) {
789 newRandomnessSource = new Clipperz.Crypto.PRNG.CryptoRandomRandomnessSource({'browserCrypto':browserCrypto});
790 _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
791 }
835 } 792 }
836
837 } 793 }
838 794
839 return _clipperz_crypt_prng_defaultPRNG; 795 return _clipperz_crypt_prng_defaultPRNG;
840}; 796};
841 797
842//############################################################################# 798//#############################################################################
843 799
844Clipperz.Crypto.PRNG.exception = { 800Clipperz.Crypto.PRNG.exception = {
845 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy") 801 NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy")
846}; 802};
847 803
848 804
849MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator); 805MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator);
diff --git a/frontend/beta/js/Clipperz/Crypto/SRP.js b/frontend/beta/js/Clipperz/Crypto/SRP.js
index 8cc80ba..8c522ad 100644
--- a/frontend/beta/js/Clipperz/Crypto/SRP.js
+++ b/frontend/beta/js/Clipperz/Crypto/SRP.js
@@ -1,326 +1,345 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) { 24try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!"; 25 throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
26} 26}
27 27
28try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) { 28try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) {
29 throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!"; 29 throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!";
30} 30}
31 31
32try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) { 32try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) {
33 throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!"; 33 throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!";
34} 34}
35 35
36if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; } 36if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; }
37 37
38Clipperz.Crypto.SRP.VERSION = "0.1"; 38Clipperz.Crypto.SRP.VERSION = "0.1";
39Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP"; 39Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP";
40 40
41//############################################################################# 41//#############################################################################
42 42
43MochiKit.Base.update(Clipperz.Crypto.SRP, { 43MochiKit.Base.update(Clipperz.Crypto.SRP, {
44 44
45 '_n': null, 45 '_n': null,
46 '_g': null, 46 '_g': null,
47 '_k': null,
48
47 //------------------------------------------------------------------------- 49 //-------------------------------------------------------------------------
48 50
49 'n': function() { 51 'n': function() {
50 if (Clipperz.Crypto.SRP._n == null) { 52 if (Clipperz.Crypto.SRP._n == null) {
51 Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16); 53 Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16);
52 } 54 }
53 55
54 return Clipperz.Crypto.SRP._n; 56 return Clipperz.Crypto.SRP._n;
55 }, 57 },
56 58
57 //------------------------------------------------------------------------- 59 //-------------------------------------------------------------------------
58 60
59 'g': function() { 61 'g': function() {
60 if (Clipperz.Crypto.SRP._g == null) { 62 if (Clipperz.Crypto.SRP._g == null) {
61 Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation) 63 Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); //eventually 5 (as suggested on the Diffi-Helmann documentation)
62 } 64 }
63 65
64 return Clipperz.Crypto.SRP._g; 66 return Clipperz.Crypto.SRP._g;
65 }, 67 },
66 68
69 'k': function() {
70 if (Clipperz.Crypto.SRP._k == null) {
71 // Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt(this.stringHash(this.n().asString() + this.g().asString()), 16);
72 Clipperz.Crypto.SRP._k = new Clipperz.Crypto.BigInt("64398bff522814e306a97cb9bfc4364b7eed16a8c17c5208a40a2bad2933c8e", 16);
73 }
74
75 return Clipperz.Crypto.SRP._k;
76 },
77
67 //----------------------------------------------------------------------------- 78 //-----------------------------------------------------------------------------
68 79
69 'exception': { 80 'exception': {
70 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue") 81 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue")
71 }, 82 },
72 83
73 //------------------------------------------------------------------------- 84 //-------------------------------------------------------------------------
74 __syntaxFix__: "syntax fix" 85 __syntaxFix__: "syntax fix"
75 86
76}); 87});
77 88
78//############################################################################# 89//#############################################################################
79// 90//
80 // S R P C o n n e c t i o n version 1.0 91 // S R P C o n n e c t i o n version 1.0
81// 92//
82//============================================================================= 93//=============================================================================
83Clipperz.Crypto.SRP.Connection = function (args) { 94Clipperz.Crypto.SRP.Connection = function (args) {
84 args = args || {}; 95 args = args || {};
85 96
86 this._C = args.C; 97 this._C = args.C;
87 this._P = args.P; 98 this._P = args.P;
88 this.hash = args.hash; 99 this.hash = args.hash;
89 100
90 this._a = null; 101 this._a = null;
91 this._A = null; 102 this._A = null;
92 103
93 this._s = null; 104 this._s = null;
94 this._B = null; 105 this._B = null;
95 106
96 this._x = null; 107 this._x = null;
97 108
98 this._u = null; 109 this._u = null;
99 this._K = null; 110 this._K = null;
100 this._M1 = null; 111 this._M1 = null;
101 this._M2 = null; 112 this._M2 = null;
102 113
103 this._sessionKey = null; 114 this._sessionKey = null;
104 115
105 return this; 116 return this;
106} 117}
107 118
108Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, { 119Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
109 120
110 'toString': function () { 121 'toString': function () {
111 return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription(); 122 return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription();
112 }, 123 },
113 124
114 //------------------------------------------------------------------------- 125 //-------------------------------------------------------------------------
115 126
116 'C': function () { 127 'C': function () {
117 return this._C; 128 return this._C;
118 }, 129 },
119 130
120 //------------------------------------------------------------------------- 131 //-------------------------------------------------------------------------
121 132
122 'P': function () { 133 'P': function () {
123 return this._P; 134 return this._P;
124 }, 135 },
125 136
126 //------------------------------------------------------------------------- 137 //-------------------------------------------------------------------------
127 138
128 'a': function () { 139 'a': function () {
129 if (this._a == null) { 140 if (this._a == null) {
130 this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16); 141 this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16);
131 // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10); 142 // this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10);
132//MochiKit.Logging.logDebug("SRP a: " + this._a);
133 } 143 }
134 144
135 return this._a; 145 return this._a;
136 }, 146 },
137 147
138 //------------------------------------------------------------------------- 148 //-------------------------------------------------------------------------
139 149
140 'A': function () { 150 'A': function () {
141 if (this._A == null) { 151 if (this._A == null) {
142 //Warning: this value should be strictly greater than zero: how should we perform this check? 152 //Warning: this value should be strictly greater than zero
143 this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n()); 153 this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n());
144 154 if (this._A.equals(0) || negative(this._A)) {
145 if (this._A.equals(0)) { 155 MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0.");
146MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0.");
147 throw Clipperz.Crypto.SRP.exception.InvalidValue; 156 throw Clipperz.Crypto.SRP.exception.InvalidValue;
148 } 157 }
149//MochiKit.Logging.logDebug("SRP A: " + this._A);
150 } 158 }
151 159
152 return this._A; 160 return this._A;
153 }, 161 },
154 162
155 //------------------------------------------------------------------------- 163 //-------------------------------------------------------------------------
156 164
157 's': function () { 165 's': function () {
158 return this._s; 166 return this._s;
159//MochiKit.Logging.logDebug("SRP s: " + this._S);
160 }, 167 },
161 168
162 'set_s': function(aValue) { 169 'set_s': function(aValue) {
163 this._s = aValue; 170 this._s = aValue;
164 }, 171 },
165 172
166 //------------------------------------------------------------------------- 173 //-------------------------------------------------------------------------
167 174
168 'B': function () { 175 'B': function () {
169 return this._B; 176 return this._B;
170 }, 177 },
171 178
172 'set_B': function(aValue) { 179 'set_B': function(aValue) {
173 //Warning: this value should be strictly greater than zero: how should we perform this check? 180 //Warning: this value should be strictly greater than zero
174 if (! aValue.equals(0)) { 181 this._B = aValue;
175 this._B = aValue; 182 if (this._B.equals(0) || negative(this._B)) {
176//MochiKit.Logging.logDebug("SRP B: " + this._B); 183 MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0.");
177 } else {
178MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0.");
179 throw Clipperz.Crypto.SRP.exception.InvalidValue; 184 throw Clipperz.Crypto.SRP.exception.InvalidValue;
180 } 185 }
181 }, 186 },
182 187
183 //------------------------------------------------------------------------- 188 //-------------------------------------------------------------------------
184 189
185 'x': function () { 190 'x': function () {
186 if (this._x == null) { 191 if (this._x == null) {
187 this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16); 192 this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16);
188//MochiKit.Logging.logDebug("SRP x: " + this._x);
189 } 193 }
190 194
191 return this._x; 195 return this._x;
192 }, 196 },
193 197
194 //------------------------------------------------------------------------- 198 //-------------------------------------------------------------------------
195 199
196 'u': function () { 200 'u': function () {
197 if (this._u == null) { 201 if (this._u == null) {
198 this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.B().asString()), 16); 202 this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.A().asString() + this.B().asString()), 16);
199//MochiKit.Logging.logDebug("SRP u: " + this._u);
200 } 203 }
201 204
202 return this._u; 205 return this._u;
203 }, 206 },
204 207
205 //------------------------------------------------------------------------- 208 //-------------------------------------------------------------------------
206 209
207 'S': function () { 210 'S': function () {
208 if (this._S == null) { 211 if (this._S == null) {
209 var bigint; 212 var bigint;
210 varsrp; 213 varsrp;
211 214
212 bigint = Clipperz.Crypto.BigInt; 215 bigint = Clipperz.Crypto.BigInt;
213 srp = Clipperz.Crypto.SRP; 216 srp = Clipperz.Crypto.SRP;
214 217
215 this._S =bigint.powerModule( 218 this._S =bigint.powerModule(
216 bigint.subtract(this.B(), bigint.powerModule(srp.g(), this.x(), srp.n())), 219 bigint.subtract(
217 bigint.add(this.a(), bigint.multiply(this.u(), this.x())), 220 this.B(),
218 srp.n() 221 bigint.multiply(
222 Clipperz.Crypto.SRP.k(),
223 bigint.powerModule(srp.g(), this.x(), srp.n())
224 )
225 ),
226 bigint.add(this.a(), bigint.multiply(this.u(), this.x())),
227 srp.n()
219 ) 228 )
220//MochiKit.Logging.logDebug("SRP S: " + this._S);
221 } 229 }
222 230
223 return this._S; 231 return this._S;
224 }, 232 },
225 233
226 //------------------------------------------------------------------------- 234 //-------------------------------------------------------------------------
227 235
228 'K': function () { 236 'K': function () {
229 if (this._K == null) { 237 if (this._K == null) {
230 this._K = this.stringHash(this.S().asString()); 238 this._K = this.stringHash(this.S().asString());
231//MochiKit.Logging.logDebug("SRP K: " + this._K);
232 } 239 }
233 240
234 return this._K; 241 return this._K;
235 }, 242 },
236 243
237 //------------------------------------------------------------------------- 244 //-------------------------------------------------------------------------
238 245
239 'M1': function () { 246 'M1': function () {
240 if (this._M1 == null) { 247 if (this._M1 == null) {
241 this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K()); 248 // this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K());
242//MochiKit.Logging.logDebug("SRP M1: " + this._M1); 249
250 //http://srp.stanford.edu/design.html
251 //User -> Host: M = H(H(N) xor H(g), H(I), s, A, B, K)
252
253 this._M1 = this.stringHash(
254 "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" +
255 this.stringHash(this.C()) +
256 this.s().asString() +
257 this.A().asString() +
258 this.B().asString() +
259 this.K()
260 );
261//console.log("M1", this._M1);
243 } 262 }
244 263
245 return this._M1; 264 return this._M1;
246 }, 265 },
247 266
248 //------------------------------------------------------------------------- 267 //-------------------------------------------------------------------------
249 268
250 'M2': function () { 269 'M2': function () {
251 if (this._M2 == null) { 270 if (this._M2 == null) {
252 this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K()); 271 this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K());
253//MochiKit.Logging.logDebug("SRP M2: " + this._M2); 272//console.log("M2", this._M2);
254 } 273 }
255 274
256 return this._M2; 275 return this._M2;
257 }, 276 },
258 277
259 //========================================================================= 278 //=========================================================================
260 279
261 'serverSideCredentialsWithSalt': function(aSalt) { 280 'serverSideCredentialsWithSalt': function(aSalt) {
262 var result; 281 var result;
263 var s, x, v; 282 var s, x, v;
264 283
265 s = aSalt; 284 s = aSalt;
266 x = this.stringHash(s + this.P()); 285 x = this.stringHash(s + this.P());
267 v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n()); 286 v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n());
268 287
269 result = {}; 288 result = {};
270 result['C'] = this.C(); 289 result['C'] = this.C();
271 result['s'] = s; 290 result['s'] = s;
272 result['v'] = v.asString(16); 291 result['v'] = v.asString(16);
273 292
274 return result; 293 return result;
275 }, 294 },
276 295
277 'serverSideCredentials': function() { 296 'serverSideCredentials': function() {
278 var result; 297 var result;
279 var s; 298 var s;
280 299
281 s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); 300 s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
282 301
283 result = this.serverSideCredentialsWithSalt(s); 302 result = this.serverSideCredentialsWithSalt(s);
284 303
285 return result; 304 return result;
286 }, 305 },
287 306
288 //========================================================================= 307 //=========================================================================
289/* 308/*
290 'computeServerSide_S': function(b) { 309 'computeServerSide_S': function(b) {
291 var result; 310 var result;
292 var v; 311 var v;
293 var bigint; 312 var bigint;
294 varsrp; 313 varsrp;
295 314
296 bigint = Clipperz.Crypto.BigInt; 315 bigint = Clipperz.Crypto.BigInt;
297 srp = Clipperz.Crypto.SRP; 316 srp = Clipperz.Crypto.SRP;
298 317
299 v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16); 318 v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16);
300 // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n()); 319 // _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n());
301 result = bigint.powerModule( 320 result = bigint.powerModule(
302 bigint.multiply( 321 bigint.multiply(
303 this.A(), 322 this.A(),
304 bigint.powerModule(v, this.u(), srp.n()) 323 bigint.powerModule(v, this.u(), srp.n())
305 ), new Clipperz.Crypto.BigInt(b, 10), srp.n() 324 ), new Clipperz.Crypto.BigInt(b, 10), srp.n()
306 ); 325 );
307 326
308 return result; 327 return result;
309 }, 328 },
310*/ 329*/
311 //========================================================================= 330 //=========================================================================
312 331
313 'stringHash': function(aValue) { 332 'stringHash': function(aValue) {
314 varresult; 333 varresult;
315 334
316 result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2); 335 result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2);
317 336
318 return result; 337 return result;
319 }, 338 },
320 339
321 //========================================================================= 340 //=========================================================================
322 __syntaxFix__: "syntax fix" 341 __syntaxFix__: "syntax fix"
323 342
324}); 343});
325 344
326//############################################################################# 345//#############################################################################
diff --git a/frontend/beta/js/Clipperz/PM/BookmarkletProcessor.js b/frontend/beta/js/Clipperz/PM/BookmarkletProcessor.js
index 2295d3f..369b9ce 100644
--- a/frontend/beta/js/Clipperz/PM/BookmarkletProcessor.js
+++ b/frontend/beta/js/Clipperz/PM/BookmarkletProcessor.js
@@ -1,283 +1,283 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } 24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } 25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
26//if (typeof(Clipperz.PM.BookmarkletProcessor) == 'undefined') { Clipperz.PM.BookmarkletProcessor = {}; } 26//if (typeof(Clipperz.PM.BookmarkletProcessor) == 'undefined') { Clipperz.PM.BookmarkletProcessor = {}; }
27//if (typeof(Clipperz.PM.BookmarkletProcessor.versions) == 'undefined') { Clipperz.PM.BookmarkletProcessor.versions = {}; } 27//if (typeof(Clipperz.PM.BookmarkletProcessor.versions) == 'undefined') { Clipperz.PM.BookmarkletProcessor.versions = {}; }
28 28
29/* 29/*
30Clipperz.PM.BookmarkletProcessor.versions['abstract'] = function(anUser, aConfiguration) { 30Clipperz.PM.BookmarkletProcessor.versions['abstract'] = function(anUser, aConfiguration) {
31 this._user = anUser; 31 this._user = anUser;
32 this._configuration = aConfiguration; 32 this._configuration = aConfiguration;
33 33
34 this._recordTitle = null; 34 this._recordTitle = null;
35 this._record = null; 35 this._record = null;
36 this._editableFields = null; 36 this._editableFields = null;
37 37
38 return this; 38 return this;
39} 39}
40 40
41 41
42Clipperz.PM.BookmarkletProcessor.versions['abstract'].prototype = MochiKit.Base.update(null, { 42Clipperz.PM.BookmarkletProcessor.versions['abstract'].prototype = MochiKit.Base.update(null, {
43 43
44 'toString': function() { 44 'toString': function() {
45 return "BookmarkletProcessor - " + this.user(); 45 return "BookmarkletProcessor - " + this.user();
46 }, 46 },
47 47
48 //------------------------------------------------------------------------- 48 //-------------------------------------------------------------------------
49 49
50 'user': function() { 50 'user': function() {
51 return this._user; 51 return this._user;
52 }, 52 },
53 53
54 //------------------------------------------------------------------------- 54 //-------------------------------------------------------------------------
55 55
56 'configuration': function() { 56 'configuration': function() {
57 return this._configuration; 57 return this._configuration;
58 }, 58 },
59 59
60 //------------------------------------------------------------------------- 60 //-------------------------------------------------------------------------
61 61
62 'record': function() { 62 'record': function() {
63 throw Clipperz.Base.exception.AbstractMethod; 63 throw Clipperz.Base.exception.AbstractMethod;
64 }, 64 },
65 65
66 //------------------------------------------------------------------------- 66 //-------------------------------------------------------------------------
67 __syntaxFix__: "syntax fix" 67 __syntaxFix__: "syntax fix"
68}); 68});
69*/ 69*/
70 70
71Clipperz.PM.BookmarkletProcessor = function(anUser, aConfiguration) { 71Clipperz.PM.BookmarkletProcessor = function(anUser, aConfiguration) {
72 this._user = anUser; 72 this._user = anUser;
73 this._configuration = aConfiguration; 73 this._configuration = aConfiguration;
74 74
75 this._recordTitle = null; 75 this._recordTitle = null;
76 this._record = null; 76 this._record = null;
77 this._editableFields = null; 77 this._editableFields = null;
78 this._favicon = null; 78 this._favicon = null;
79 79
80 return this; 80 return this;
81} 81}
82 82
83Clipperz.PM.BookmarkletProcessor.prototype = MochiKit.Base.update(null, { 83Clipperz.PM.BookmarkletProcessor.prototype = MochiKit.Base.update(null, {
84 84
85 'toString': function() { 85 'toString': function() {
86 return "BookmarkletProcessor - " + this.user(); 86 return "BookmarkletProcessor - " + this.user();
87 }, 87 },
88 88
89 //------------------------------------------------------------------------- 89 //-------------------------------------------------------------------------
90 90
91 'user': function() { 91 'user': function() {
92 return this._user; 92 return this._user;
93 }, 93 },
94 94
95 //------------------------------------------------------------------------- 95 //-------------------------------------------------------------------------
96 96
97 'configuration': function() { 97 'configuration': function() {
98 return this._configuration; 98 return this._configuration;
99 }, 99 },
100 100
101 //------------------------------------------------------------------------- 101 //-------------------------------------------------------------------------
102 102
103 'recordTitle': function() { 103 'recordTitle': function() {
104 if (this._recordTitle == null) { 104 if (this._recordTitle == null) {
105 this._recordTitle = this.configuration().page.title; 105 this._recordTitle = this.configuration().page.title;
106 } 106 }
107 107
108 return this._recordTitle; 108 return this._recordTitle;
109 }, 109 },
110 110
111 //------------------------------------------------------------------------- 111 //-------------------------------------------------------------------------
112 112
113 'fields': function() { 113 'fields': function() {
114 return this.configuration().form.inputs; 114 return this.configuration().form.inputs;
115 }, 115 },
116 116
117 //------------------------------------------------------------------------- 117 //-------------------------------------------------------------------------
118 118
119 'editableFields': function() { 119 'editableFields': function() {
120 if (this._editableFields == null) { 120 if (this._editableFields == null) {
121 this._editableFields = MochiKit.Base.filter(function(aField) { 121 this._editableFields = MochiKit.Base.filter(function(aField) {
122 var result; 122 var result;
123 var type; 123 var type;
124 124
125 type = aField['type'].toLowerCase(); 125 type = aField['type'].toLowerCase();
126 result = ((type != 'hidden') && (type != 'submit') && (type != 'checkbox') && (type != 'radio') && (type != 'select')); 126 result = ((type != 'hidden') && (type != 'submit') && (type != 'checkbox') && (type != 'radio') && (type != 'select'));
127 127
128 return result; 128 return result;
129 }, this.fields()) 129 }, this.fields())
130 } 130 }
131 131
132 return this._editableFields; 132 return this._editableFields;
133 }, 133 },
134 134
135 //------------------------------------------------------------------------- 135 //-------------------------------------------------------------------------
136 136
137 'hostname': function() { 137 'hostname': function() {
138 if (this._hostname == null) { 138 if (this._hostname == null) {
139 var actionUrl; 139 var actionUrl;
140 140
141 actionUrl = this.configuration()['form']['attributes']['action']; 141 actionUrl = Clipperz.Base.sanitizeUrl(this.configuration()['form']['attributes']['action']);
142//MochiKit.Logging.logDebug("+++ actionUrl: " + actionUrl); 142//MochiKit.Logging.logDebug("+++ actionUrl: " + actionUrl);
143 this._hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1'); 143 this._hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1');
144 } 144 }
145 145
146 return this._hostname; 146 return this._hostname;
147 }, 147 },
148 148
149 'favicon': function() { 149 'favicon': function() {
150 if (this._favicon == null) { 150 if (this._favicon == null) {
151 this._favicon = "http://" + this.hostname() + "/favicon.ico"; 151 this._favicon = "http://" + this.hostname() + "/favicon.ico";
152//MochiKit.Logging.logDebug("+++ favicon: " + this._favicon); 152//MochiKit.Logging.logDebug("+++ favicon: " + this._favicon);
153 } 153 }
154 154
155 return this._favicon; 155 return this._favicon;
156 }, 156 },
157 157
158 //------------------------------------------------------------------------- 158 //-------------------------------------------------------------------------
159 159
160 'record': function() { 160 'record': function() {
161 if (this._record == null) { 161 if (this._record == null) {
162 var record; 162 var record;
163 var recordVersion; 163 var recordVersion;
164 var directLogin; 164 var directLogin;
165 var bindings; 165 var bindings;
166 var i,c; 166 var i,c;
167 167
168 record = new Clipperz.PM.DataModel.Record({ 168 record = new Clipperz.PM.DataModel.Record({
169 label:this.recordTitle(), 169 label:this.recordTitle(),
170 notes:"", 170 notes:"",
171 user:this.user() 171 user:this.user()
172 }); 172 });
173 recordVersion = new Clipperz.PM.DataModel.RecordVersion(record, {}) 173 recordVersion = new Clipperz.PM.DataModel.RecordVersion(record, {})
174 record.setCurrentVersion(recordVersion); 174 record.setCurrentVersion(recordVersion);
175 175
176 bindings = {}; 176 bindings = {};
177 177
178 c = this.editableFields().length; 178 c = this.editableFields().length;
179 for (i=0; i<c; i++) { 179 for (i=0; i<c; i++) {
180 var formField; 180 var formField;
181 var recordField; 181 var recordField;
182 182
183//MochiKit.Logging.logDebug(">>> adding a field"); 183//MochiKit.Logging.logDebug(">>> adding a field");
184 formField = this.editableFields()[i]; 184 formField = this.editableFields()[i];
185 recordField = new Clipperz.PM.DataModel.RecordField({ 185 recordField = new Clipperz.PM.DataModel.RecordField({
186 recordVersion:recordVersion, 186 recordVersion:recordVersion,
187 label:formField['name'], 187 label:formField['name'],
188 value:formField['value'], 188 value:formField['value'],
189 type:Clipperz.PM.Strings.inputTypeToRecordFieldType[formField['type']], 189 type:Clipperz.PM.Strings.inputTypeToRecordFieldType[formField['type']],
190 hidden:false 190 hidden:false
191 }); 191 });
192 recordVersion.addField(recordField); 192 recordVersion.addField(recordField);
193 193
194 bindings[formField['name']] = recordField.key(); 194 bindings[formField['name']] = recordField.key();
195//MochiKit.Logging.logDebug("<<< adding a field"); 195//MochiKit.Logging.logDebug("<<< adding a field");
196 } 196 }
197 197
198 directLogin = new Clipperz.PM.DataModel.DirectLogin({ 198 directLogin = new Clipperz.PM.DataModel.DirectLogin({
199 record:record, 199 record:record,
200 label:this.recordTitle() + Clipperz.PM.Strings['newDirectLoginLabelSuffix'], 200 label:this.recordTitle() + Clipperz.PM.Strings['newDirectLoginLabelSuffix'],
201 // bookmarkletVersion:this.version(), 201 // bookmarkletVersion:this.version(),
202 bookmarkletVersion:'0.2', 202 bookmarkletVersion:'0.2',
203 favicon:this.favicon(), 203 favicon:this.favicon(),
204 formData:this.configuration()['form'], 204 formData:this.configuration()['form'],
205 bindingData:bindings 205 bindingData:bindings
206 }); 206 });
207 record.addDirectLogin(directLogin); 207 record.addDirectLogin(directLogin);
208 208
209 this.user().addRecord(record); 209 this.user().addRecord(record);
210 210
211 this._record = record; 211 this._record = record;
212 } 212 }
213 213
214 return this._record; 214 return this._record;
215 }, 215 },
216 216
217 //------------------------------------------------------------------------- 217 //-------------------------------------------------------------------------
218 __syntaxFix__: "syntax fix" 218 __syntaxFix__: "syntax fix"
219}); 219});
220 220
221//############################################################################# 221//#############################################################################
222 222
223Clipperz.PM.BookmarkletProcessor.createRecordFromBookmarkletConfiguration = function(anUser, aConfiguration) { 223Clipperz.PM.BookmarkletProcessor.createRecordFromBookmarkletConfiguration = function(anUser, aConfiguration) {
224 var processor; 224 var processor;
225 225
226 processor = new Clipperz.PM.BookmarkletProcessor(anUser, aConfiguration); 226 processor = new Clipperz.PM.BookmarkletProcessor(anUser, aConfiguration);
227 227
228 return processor.record(); 228 return processor.record();
229}; 229};
230 230
231//----------------------------------------------------------------------------- 231//-----------------------------------------------------------------------------
232 232
233Clipperz.PM.BookmarkletProcessor.sanitizeBookmarkletConfiguration = function(aConfiguration) { 233Clipperz.PM.BookmarkletProcessor.sanitizeBookmarkletConfiguration = function(aConfiguration) {
234 var result; 234 var result;
235 235
236 //throw "XSS Bookmarklet attempt"; 236 //throw "XSS Bookmarklet attempt";
237 237
238 result = aConfiguration; 238 result = aConfiguration;
239 239
240 return result; 240 return result;
241}; 241};
242 242
243//----------------------------------------------------------------------------- 243//-----------------------------------------------------------------------------
244 244
245Clipperz.PM.BookmarkletProcessor.checkBookmarkletConfiguration = function(aConfiguration, aButton, aCallback) { 245Clipperz.PM.BookmarkletProcessor.checkBookmarkletConfiguration = function(aConfiguration, aButton, aCallback) {
246 var result; 246 var result;
247 247
248 try { 248 try {
249 result = Clipperz.Base.evalJSON(aConfiguration); 249 result = Clipperz.Base.evalJSON(aConfiguration);
250 result = Clipperz.PM.BookmarkletProcessor.sanitizeBookmarkletConfiguration(result); 250 result = Clipperz.PM.BookmarkletProcessor.sanitizeBookmarkletConfiguration(result);
251 251
252 if (result['version'] != '0.2.3') { 252 if (result['version'] != '0.2.3') {
253 throw "WrongBookmarkletVersion"; 253 throw "WrongBookmarkletVersion";
254 } 254 }
255 } catch (exception) { 255 } catch (exception) {
256 var title; 256 var title;
257 var message; 257 var message;
258 258
259 if (exception == "WrongBookmarkletVersion") { 259 if (exception == "WrongBookmarkletVersion") {
260 title = Clipperz.PM.Strings['newRecordPanelWrongBookmarkletVersionExceptionTitle']; 260 title = Clipperz.PM.Strings['newRecordPanelWrongBookmarkletVersionExceptionTitle'];
261 message = Clipperz.PM.Strings['newRecordPanelWrongBookmarkletVersionExceptionMessage']; 261 message = Clipperz.PM.Strings['newRecordPanelWrongBookmarkletVersionExceptionMessage'];
262 } else { 262 } else {
263 title = Clipperz.PM.Strings['newRecordPanelGeneralExceptionTitle']; 263 title = Clipperz.PM.Strings['newRecordPanelGeneralExceptionTitle'];
264 message = Clipperz.PM.Strings['newRecordPanelGeneralExceptionMessage']; 264 message = Clipperz.PM.Strings['newRecordPanelGeneralExceptionMessage'];
265 } 265 }
266 Clipperz.PM.Components.MessageBox().show({ 266 Clipperz.PM.Components.MessageBox().show({
267 title:title, 267 title:title,
268 text:message, 268 text:message,
269 width:240, 269 width:240,
270 fn:aCallback, 270 fn:aCallback,
271 closable:false, 271 closable:false,
272 showProgressBar:false, 272 showProgressBar:false,
273 showCloseButton:false, 273 showCloseButton:false,
274 buttons:{'ok':Clipperz.PM.Strings['newRecordPanelExceptionPanelCloseButtonLabel']} 274 buttons:{'ok':Clipperz.PM.Strings['newRecordPanelExceptionPanelCloseButtonLabel']}
275 }, aButton); 275 }, aButton);
276 276
277 throw exception; 277 throw exception;
278 } 278 }
279 279
280 return result; 280 return result;
281}; 281};
282 282
283//----------------------------------------------------------------------------- 283//-----------------------------------------------------------------------------
diff --git a/frontend/beta/js/Clipperz/PM/Components/RecordDetail/DirectLoginBindingComponent.js b/frontend/beta/js/Clipperz/PM/Components/RecordDetail/DirectLoginBindingComponent.js
index 0e4640e..a5a4697 100644
--- a/frontend/beta/js/Clipperz/PM/Components/RecordDetail/DirectLoginBindingComponent.js
+++ b/frontend/beta/js/Clipperz/PM/Components/RecordDetail/DirectLoginBindingComponent.js
@@ -1,169 +1,169 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } 24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } 25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
26if (typeof(Clipperz.PM.Components) == 'undefined') { Clipperz.PM.Components = {}; } 26if (typeof(Clipperz.PM.Components) == 'undefined') { Clipperz.PM.Components = {}; }
27if (typeof(Clipperz.PM.Components.RecordDetail) == 'undefined') { Clipperz.PM.Components.RecordDetail = {}; } 27if (typeof(Clipperz.PM.Components.RecordDetail) == 'undefined') { Clipperz.PM.Components.RecordDetail = {}; }
28 28
29//############################################################################# 29//#############################################################################
30 30
31Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent = function(anElement, args) { 31Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent = function(anElement, args) {
32//MochiKit.Logging.logDebug(">>> new DirectLoginBindingComponent"); 32//MochiKit.Logging.logDebug(">>> new DirectLoginBindingComponent");
33 args = args || {}; 33 args = args || {};
34 34
35 Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent.superclass.constructor.call(this, anElement, args); 35 Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent.superclass.constructor.call(this, anElement, args);
36 36
37 this._directLoginBinding = args.directLoginBinding || null; 37 this._directLoginBinding = args.directLoginBinding || null;
38 this.render(); 38 this.render();
39 39
40 Clipperz.NotificationCenter.register(this.record(), 'addNewRecordField',this, 'syncAndUpdateEditMode'); 40 Clipperz.NotificationCenter.register(this.record(), 'addNewRecordField',this, 'syncAndUpdateEditMode');
41 Clipperz.NotificationCenter.register(this.record(), 'removedField', this, 'syncAndUpdateEditMode'); 41 Clipperz.NotificationCenter.register(this.record(), 'removedField', this, 'syncAndUpdateEditMode');
42 Clipperz.NotificationCenter.register(this.record(), 'updatedFieldLabel',this, 'syncAndUpdateEditMode'); 42 Clipperz.NotificationCenter.register(this.record(), 'updatedFieldLabel',this, 'syncAndUpdateEditMode');
43//MochiKit.Logging.logDebug("<<< new DirectLoginBindingComponent"); 43//MochiKit.Logging.logDebug("<<< new DirectLoginBindingComponent");
44 44
45 return this; 45 return this;
46} 46}
47 47
48//============================================================================= 48//=============================================================================
49 49
50YAHOO.extendX(Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent, Clipperz.PM.Components.RecordDetail.AbstractComponent, { 50YAHOO.extendX(Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent, Clipperz.PM.Components.RecordDetail.AbstractComponent, {
51 51
52 'toString': function() { 52 'toString': function() {
53 return "Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent component"; 53 return "Clipperz.PM.Components.RecordDetail.DirectLoginBindingComponent component";
54 }, 54 },
55 55
56 //------------------------------------------------------------------------- 56 //-------------------------------------------------------------------------
57 57
58 'directLoginBinding': function() { 58 'directLoginBinding': function() {
59 return this._directLoginBinding; 59 return this._directLoginBinding;
60 }, 60 },
61 61
62 //------------------------------------------------------------------------- 62 //-------------------------------------------------------------------------
63 63
64 'render': function() { 64 'render': function() {
65 // Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'span', style:'font-weight:bold;', html:this.directLoginBinding().key()}) 65 // Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'span', style:'font-weight:bold;', html:this.directLoginBinding().key()})
66 // Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'span', html:this.directLoginBinding().value()}) 66 // Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'span', html:this.directLoginBinding().value()})
67//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.render"); 67//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.render");
68 Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'td', cls:'directLoginBindingLabelTD', children:[ 68 Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'td', cls:'directLoginBindingLabelTD', children:[
69 {tag:'span', html:this.directLoginBinding().key()} 69 {tag:'span', html:this.directLoginBinding().key()}
70 ]}); 70 ]});
71//MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.render - 1"); 71//MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.render - 1");
72 Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'td', cls:'directLoginBindingValueTD', children:[ 72 Clipperz.YUI.DomHelper.append(this.element().dom, {tag:'td', cls:'directLoginBindingValueTD', children:[
73 {tag:'div', id:this.getId('editModeBox'), children:[ 73 {tag:'div', id:this.getId('editModeBox'), children:[
74 {tag:'select', id:this.getId('select'), children:this.recordFieldOptions()} 74 {tag:'select', id:this.getId('select'), children:this.recordFieldOptions()}
75 ]}, 75 ]},
76 {tag:'div', id:this.getId('viewModeBox'), children:[ 76 {tag:'div', id:this.getId('viewModeBox'), children:[
77 {tag:'span', id:this.getId('viewValue'), html:""} 77 {tag:'span', id:this.getId('viewValue'), html:""}
78 ]} 78 ]}
79 ]}); 79 ]});
80//MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.render - 2"); 80//MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.render - 2");
81 this.getElement('editModeBox').setVisibilityMode(YAHOO.ext.Element.DISPLAY); 81 this.getElement('editModeBox').setVisibilityMode(YAHOO.ext.Element.DISPLAY);
82 this.getElement('viewModeBox').setVisibilityMode(YAHOO.ext.Element.DISPLAY); 82 this.getElement('viewModeBox').setVisibilityMode(YAHOO.ext.Element.DISPLAY);
83 83
84 this.update(); 84 this.update();
85//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.render"); 85//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.render");
86 }, 86 },
87 87
88 //------------------------------------------------------------------------- 88 //-------------------------------------------------------------------------
89 89
90 'recordFieldOptions': function() { 90 'recordFieldOptions': function() {
91 varresult; 91 varresult;
92 var option; 92 var option;
93 varrecordFieldKey; 93 varrecordFieldKey;
94 varrecordFields; 94 varrecordFields;
95 95
96//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.recordFieldOptions"); 96//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.recordFieldOptions");
97 recordFields = this.directLoginBinding().directLogin().record().currentVersion().fields(); 97 recordFields = this.directLoginBinding().directLogin().record().currentVersion().fields();
98 result = []; 98 result = [];
99 option = {tag:'option', value:null, html:'---'}; 99 option = {tag:'option', value:null, html:'---'};
100 result.push(option); 100 result.push(option);
101 for (recordFieldKey in recordFields) { 101 for (recordFieldKey in recordFields) {
102 //TODO: remove the value: field and replace it with element.dom.value = <some value> 102 //TODO: remove the value: field and replace it with element.dom.value = <some value>
103 option = {tag:'option', value:recordFieldKey, html:recordFields[recordFieldKey].label()} 103 option = {tag:'option', value:recordFieldKey, html:Clipperz.Base.sanitizeString(recordFields[recordFieldKey].label())}
104 if (recordFieldKey == this.directLoginBinding().fieldKey()) { 104 if (recordFieldKey == this.directLoginBinding().fieldKey()) {
105 option['selected'] = true; 105 option['selected'] = true;
106 } 106 }
107 result.push(option); 107 result.push(option);
108 } 108 }
109//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.recordFieldOptions"); 109//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.recordFieldOptions");
110 110
111 return result; 111 return result;
112 }, 112 },
113 113
114 //------------------------------------------------------------------------- 114 //-------------------------------------------------------------------------
115 115
116 'syncAndUpdateEditMode': function() { 116 'syncAndUpdateEditMode': function() {
117 this.synchronizeComponentValues(); 117 this.synchronizeComponentValues();
118 this.updateEditMode(); 118 this.updateEditMode();
119 }, 119 },
120 120
121 'updateEditMode': function() { 121 'updateEditMode': function() {
122 varselectElementBox; 122 varselectElementBox;
123 123
124//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.updateEditMode"); 124//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.updateEditMode");
125 this.getElement('viewModeBox').hide(); 125 this.getElement('viewModeBox').hide();
126 126
127 selectElementBox = this.getElement('editModeBox'); 127 selectElementBox = this.getElement('editModeBox');
128 selectElementBox.update(""); 128 selectElementBox.update("");
129 129
130 Clipperz.YUI.DomHelper.append(selectElementBox.dom, {tag:'select', id:this.getId('select'), children:this.recordFieldOptions()}); 130 Clipperz.YUI.DomHelper.append(selectElementBox.dom, {tag:'select', id:this.getId('select'), children:this.recordFieldOptions()});
131 131
132/* 132/*
133 selectElement = this.getElement('select'); 133 selectElement = this.getElement('select');
134 134
135 selectElement.update(""); 135 selectElement.update("");
136 MochiKit.Iter.forEach(this.recordFieldOptions(), function(anOption) { 136 MochiKit.Iter.forEach(this.recordFieldOptions(), function(anOption) {
137 Clipperz.YUI.DomHelper.append(selectElement.dom, anOption); 137 Clipperz.YUI.DomHelper.append(selectElement.dom, anOption);
138 }); 138 });
139*/ 139*/
140 140
141 141
142 this.getElement('editModeBox').show(); 142 this.getElement('editModeBox').show();
143//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.updateEditMode"); 143//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.updateEditMode");
144 }, 144 },
145 145
146 //------------------------------------------------------------------------- 146 //-------------------------------------------------------------------------
147 147
148 'updateViewMode': function() { 148 'updateViewMode': function() {
149//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.updateViewMode"); 149//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.updateViewMode");
150 this.getElement('editModeBox').hide(); 150 this.getElement('editModeBox').hide();
151 this.getElement('viewModeBox').show(); 151 this.getElement('viewModeBox').show();
152 152
153 this.getElement('viewValue').update(this.directLoginBinding().field().label()); 153 this.getElement('viewValue').update(Clipperz.Base.sanitizeString(this.directLoginBinding().field().label()));
154//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.updateViewMode"); 154//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.updateViewMode");
155 }, 155 },
156 156
157 //------------------------------------------------------------------------- 157 //-------------------------------------------------------------------------
158 158
159 'synchronizeComponentValues': function() { 159 'synchronizeComponentValues': function() {
160//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.synchronizeComponentValues") 160//MochiKit.Logging.logDebug(">>> DirectLoginBindingComponent.synchronizeComponentValues")
161//MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.synchronizeComponentValues - 1 - " + this.getId('select')); 161//MochiKit.Logging.logDebug("--- DirectLoginBindingComponent.synchronizeComponentValues - 1 - " + this.getId('select'));
162 this.directLoginBinding().setFieldKey(this.getDom('select').value); 162 this.directLoginBinding().setFieldKey(this.getDom('select').value);
163//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.synchronizeComponentValues"); 163//MochiKit.Logging.logDebug("<<< DirectLoginBindingComponent.synchronizeComponentValues");
164 }, 164 },
165 165
166 //------------------------------------------------------------------------- 166 //-------------------------------------------------------------------------
167 __syntaxFix__: "syntax fix" 167 __syntaxFix__: "syntax fix"
168}); 168});
169 169
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js b/frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js
index c0cfa3c..56d9d59 100644
--- a/frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js
+++ b/frontend/beta/js/Clipperz/PM/DataModel/DirectLogin.js
@@ -1,531 +1,539 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } 24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } 25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
26if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; } 26if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
27 27
28 28
29//############################################################################# 29//#############################################################################
30 30
31Clipperz.PM.DataModel.DirectLogin = function(args) { 31Clipperz.PM.DataModel.DirectLogin = function(args) {
32//MochiKit.Logging.logDebug(">>> new Clipperz.PM.DataModel.DirectLogin"); 32//MochiKit.Logging.logDebug(">>> new Clipperz.PM.DataModel.DirectLogin");
33//console.log(">>> new Clipperz.PM.DataModel.DirectLogin - args: %o", args); 33//console.log(">>> new Clipperz.PM.DataModel.DirectLogin - args: %o", args);
34//console.log("--- formData: %s", Clipperz.Base.serializeJSON(args.formData)); 34//console.log("--- formData: %s", Clipperz.Base.serializeJSON(args.formData));
35 args = args || {}; 35 args = args || {};
36 36
37//MochiKit.Logging.logDebug("--- new Clipperz.PM.DataModel.DirectLogin - args: " + Clipperz.Base.serializeJSON(MochiKit.Base.keys(args))); 37//MochiKit.Logging.logDebug("--- new Clipperz.PM.DataModel.DirectLogin - args: " + Clipperz.Base.serializeJSON(MochiKit.Base.keys(args)));
38 this._record = args.record || null; 38 this._record = args.record || null;
39 this._label = args.label || "unnamed record" 39 this._label = args.label || "unnamed record"
40 this._reference = args.reference || Clipperz.PM.Crypto.randomKey(); 40 this._reference = args.reference || Clipperz.PM.Crypto.randomKey();
41 this._favicon = args.favicon || null; 41 this._favicon = Clipperz.Base.sanitizeFavicon(args.favicon) || null;
42 this._bookmarkletVersion = args.bookmarkletVersion || "0.1"; 42 this._bookmarkletVersion = args.bookmarkletVersion || "0.1";
43 43
44 this._directLoginInputs = null; 44 this._directLoginInputs = null;
45 45
46 this._formValues = args.formValues || {}; 46 this._formValues = args.formValues || {};
47 this.setFormData(args.formData || null); 47 this.setFormData(args.formData || null);
48//console.log("=== formData: %o", this.formData()); 48//console.log("=== formData: %o", this.formData());
49 49
50 if (args.legacyBindingData == null) { 50 if (args.legacyBindingData == null) {
51 this.setBindingData(args.bindingData || null); 51 this.setBindingData(args.bindingData || null);
52 } else { 52 } else {
53 this.setLegacyBindingData(args.legacyBindingData); 53 this.setLegacyBindingData(args.legacyBindingData);
54 } 54 }
55 55
56 this._fixedFavicon = null; 56 this._fixedFavicon = null;
57 57
58 //this._formValues = args.formValues || (this.hasValuesToSet() ? {} : null); 58 //this._formValues = args.formValues || (this.hasValuesToSet() ? {} : null);
59//MochiKit.Logging.logDebug("<<< new Clipperz.PM.DataModel.DirectLogin"); 59//MochiKit.Logging.logDebug("<<< new Clipperz.PM.DataModel.DirectLogin");
60 60
61 return this; 61 return this;
62} 62}
63 63
64Clipperz.PM.DataModel.DirectLogin.prototype = MochiKit.Base.update(null, { 64Clipperz.PM.DataModel.DirectLogin.prototype = MochiKit.Base.update(null, {
65 65
66 'remove': function() { 66 'remove': function() {
67 this.record().removeDirectLogin(this); 67 this.record().removeDirectLogin(this);
68 }, 68 },
69 69
70 //------------------------------------------------------------------------- 70 //-------------------------------------------------------------------------
71 71
72 'record': function() { 72 'record': function() {
73 return this._record; 73 return this._record;
74 }, 74 },
75 75
76 //------------------------------------------------------------------------- 76 //-------------------------------------------------------------------------
77 77
78 'user': function() { 78 'user': function() {
79 return this.record().user(); 79 return this.record().user();
80 }, 80 },
81 81
82 //------------------------------------------------------------------------- 82 //-------------------------------------------------------------------------
83 83
84 'reference': function() { 84 'reference': function() {
85 return this._reference; 85 return this._reference;
86 }, 86 },
87 87
88 //------------------------------------------------------------------------- 88 //-------------------------------------------------------------------------
89 89
90 'label': function() { 90 'label': function() {
91 return this._label; 91 return this._label;
92 }, 92 },
93 93
94 'setLabel': function(aValue) { 94 'setLabel': function(aValue) {
95 this._label = aValue; 95 this._label = aValue;
96 }, 96 },
97 97
98 //------------------------------------------------------------------------- 98 //-------------------------------------------------------------------------
99 99
100 'favicon': function() { 100 'favicon': function() {
101 if (this._favicon == null) { 101 if (this._favicon == null) {
102 varactionUrl; 102 varactionUrl;
103 var hostname; 103 var hostname;
104 104
105 actionUrl = this.formData()['attributes']['action']; 105 actionUrl = this.action();
106 hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1'); 106 hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1');
107 this._favicon = "http://" + hostname + "/favicon.ico"; 107 this._favicon = Clipperz.Base.sanitizeFavicon("http://" + hostname + "/favicon.ico");
108 } 108 }
109 109
110 return this._favicon; 110 return this._favicon;
111 }, 111 },
112 112
113 //------------------------------------------------------------------------- 113 //-------------------------------------------------------------------------
114 114
115 'fixedFavicon': function() { 115 'fixedFavicon': function() {
116 var result; 116 var result;
117 117
118 if (this._fixedFavicon == null) { 118 if (this._fixedFavicon == null) {
119 result = this.favicon(); 119 result = this.favicon();
120 120
121 if (Clipperz_IEisBroken) { 121 if (Clipperz_IEisBroken) {
122 if (this.user().preferences().disableUnsecureFaviconLoadingForIE()) { 122 if (this.user().preferences().disableUnsecureFaviconLoadingForIE()) {
123 if (result.indexOf('https://') != 0) { 123 if (result.indexOf('https://') != 0) {
124 result = Clipperz.PM.Strings['defaultFaviconUrl_IE']; 124 result = Clipperz.PM.Strings['defaultFaviconUrl_IE'];
125 this.setFixedFavicon(result); 125 this.setFixedFavicon(result);
126 } 126 }
127 } 127 }
128 } 128 }
129 } else { 129 } else {
130 result = this._fixedFavicon; 130 result = this._fixedFavicon;
131 } 131 }
132 132
133 return result; 133 return result;
134 }, 134 },
135 135
136 'setFixedFavicon': function(aValue) { 136 'setFixedFavicon': function(aValue) {
137 this._fixedFavicon = aValue; 137 this._fixedFavicon = aValue;
138 }, 138 },
139 139
140 'action': function () {
141 varresult;
142
143 result = Clipperz.Base.sanitizeUrl(this.formData()['attributes']['action']);
144
145 return result;
146 },
147
140 //------------------------------------------------------------------------- 148 //-------------------------------------------------------------------------
141 149
142 'bookmarkletVersion': function() { 150 'bookmarkletVersion': function() {
143 return this._bookmarkletVersion; 151 return this._bookmarkletVersion;
144 }, 152 },
145 153
146 'setBookmarkletVersion': function(aValue) { 154 'setBookmarkletVersion': function(aValue) {
147 this._bookmarkletVersion = aValue; 155 this._bookmarkletVersion = aValue;
148 }, 156 },
149 157
150 //------------------------------------------------------------------------- 158 //-------------------------------------------------------------------------
151 159
152 'formData': function() { 160 'formData': function() {
153 return this._formData; 161 return this._formData;
154 }, 162 },
155 163
156 'setFormData': function(aValue) { 164 'setFormData': function(aValue) {
157 var formData; 165 var formData;
158 166
159//MochiKit.Logging.logDebug(">>> DirectLogin.setFormData - " + Clipperz.Base.serializeJSON(aValue)); 167//MochiKit.Logging.logDebug(">>> DirectLogin.setFormData - " + Clipperz.Base.serializeJSON(aValue));
160 switch (this.bookmarkletVersion()) { 168 switch (this.bookmarkletVersion()) {
161 case "0.2": 169 case "0.2":
162 formData = aValue; 170 formData = aValue;
163 break; 171 break;
164 case "0.1": 172 case "0.1":
165//MochiKit.Logging.logDebug("--- DirectLogin.setFormData - fixing form data from bookmarklet version 0.1"); 173//MochiKit.Logging.logDebug("--- DirectLogin.setFormData - fixing form data from bookmarklet version 0.1");
166 formData = this.fixFormDataFromBookmarkletVersion_0_1(aValue); 174 formData = this.fixFormDataFromBookmarkletVersion_0_1(aValue);
167 break; 175 break;
168 } 176 }
169 177
170 this._formData = aValue; 178 this._formData = aValue;
171 this.setBookmarkletVersion("0.2"); 179 this.setBookmarkletVersion("0.2");
172 180
173//MochiKit.Logging.logDebug("--- DirectLogin.setFormData - formData: " + Clipperz.Base.serializeJSON(formData)); 181//MochiKit.Logging.logDebug("--- DirectLogin.setFormData - formData: " + Clipperz.Base.serializeJSON(formData));
174 if (formData != null) { 182 if (formData != null) {
175 var i,c; 183 var i,c;
176 184
177 this._directLoginInputs = []; 185 this._directLoginInputs = [];
178 c = formData['inputs'].length; 186 c = formData['inputs'].length;
179 for (i=0; i<c; i++) { 187 for (i=0; i<c; i++) {
180 var directLoginInput; 188 var directLoginInput;
181 189
182 directLoginInput = new Clipperz.PM.DataModel.DirectLoginInput(this, formData['inputs'][i]); 190 directLoginInput = new Clipperz.PM.DataModel.DirectLoginInput(this, formData['inputs'][i]);
183 this._directLoginInputs.push(directLoginInput); 191 this._directLoginInputs.push(directLoginInput);
184 } 192 }
185 } 193 }
186//MochiKit.Logging.logDebug("<<< DirectLogin.setFormData"); 194//MochiKit.Logging.logDebug("<<< DirectLogin.setFormData");
187 }, 195 },
188 196
189 'fixFormDataFromBookmarkletVersion_0_1': function(aValue) { 197 'fixFormDataFromBookmarkletVersion_0_1': function(aValue) {
190//{"type":"radio", "name":"action", "value":"new-user", "checked":false }, { "type":"radio", "name":"action", "value":"sign-in", "checked":true } 198//{"type":"radio", "name":"action", "value":"new-user", "checked":false }, { "type":"radio", "name":"action", "value":"sign-in", "checked":true }
191 // || 199 // ||
192 // \ / 200 // \ /
193 // \/ 201 // \/
194//{"name":"dominio", "type":"radio", "options":[{"value":"@alice.it", "checked":true}, {"value":"@tin.it", "checked":false}, {"value":"@virgilio.it", "checked":false}, {"value":"@tim.it", "checked":false}]} 202//{"name":"dominio", "type":"radio", "options":[{"value":"@alice.it", "checked":true}, {"value":"@tin.it", "checked":false}, {"value":"@virgilio.it", "checked":false}, {"value":"@tim.it", "checked":false}]}
195 var result; 203 var result;
196 var inputs; 204 var inputs;
197 var updatedInputs; 205 var updatedInputs;
198 var radios; 206 var radios;
199 207
200//MochiKit.Logging.logDebug(">>> DirectLogin.fixFormDataFromBookmarkletVersion_0_1"); 208//MochiKit.Logging.logDebug(">>> DirectLogin.fixFormDataFromBookmarkletVersion_0_1");
201 result = aValue; 209 result = aValue;
202 inputs = aValue['inputs']; 210 inputs = aValue['inputs'];
203 211
204 updatedInputs = MochiKit.Base.filter(function(anInput) { 212 updatedInputs = MochiKit.Base.filter(function(anInput) {
205 varresult; 213 varresult;
206 var type; 214 var type;
207 215
208 type = anInput['type'] || 'text'; 216 type = anInput['type'] || 'text';
209 result = type.toLowerCase() != 'radio'; 217 result = type.toLowerCase() != 'radio';
210 218
211 return result; 219 return result;
212 }, inputs); 220 }, inputs);
213 radios = MochiKit.Base.filter(function(anInput) { 221 radios = MochiKit.Base.filter(function(anInput) {
214 varresult; 222 varresult;
215 var type; 223 var type;
216 224
217 type = anInput['type'] || 'text'; 225 type = anInput['type'] || 'text';
218 result = type.toLowerCase() == 'radio'; 226 result = type.toLowerCase() == 'radio';
219 227
220 return result; 228 return result;
221 }, inputs); 229 }, inputs);
222 230
223 if (radios.length > 0) { 231 if (radios.length > 0) {
224 var updatedRadios; 232 var updatedRadios;
225 233
226 updatedRadios = {}; 234 updatedRadios = {};
227 MochiKit.Iter.forEach(radios, MochiKit.Base.bind(function(aRadio) { 235 MochiKit.Iter.forEach(radios, MochiKit.Base.bind(function(aRadio) {
228 varradioConfiguration; 236 varradioConfiguration;
229 237
230 radioConfiguration = updatedRadios[aRadio['name']]; 238 radioConfiguration = updatedRadios[aRadio['name']];
231 if (radioConfiguration == null) { 239 if (radioConfiguration == null) {
232 radioConfiguration = {type:'radio', name:aRadio['name'], options:[]}; 240 radioConfiguration = {type:'radio', name:aRadio['name'], options:[]};
233 updatedRadios[aRadio['name']] = radioConfiguration; 241 updatedRadios[aRadio['name']] = radioConfiguration;
234 } 242 }
235 243
236 //TODO: remove the value: field and replace it with element.dom.value = <some value> 244 //TODO: remove the value: field and replace it with element.dom.value = <some value>
237 radioConfiguration.options.push({value:aRadio['value'], checked:aRadio['checked']}); 245 radioConfiguration.options.push({value:aRadio['value'], checked:aRadio['checked']});
238 246
239 if ((aRadio['checked'] == true) && (this.formValues()[aRadio['name']] == null)) { 247 if ((aRadio['checked'] == true) && (this.formValues()[aRadio['name']] == null)) {
240//MochiKit.Logging.logDebug("+++ setting value '" + aRadio['value'] + "' for key: '" + aRadio['name'] + "'"); 248//MochiKit.Logging.logDebug("+++ setting value '" + aRadio['value'] + "' for key: '" + aRadio['name'] + "'");
241 this.formValues()[aRadio['name']] = aRadio['value']; 249 this.formValues()[aRadio['name']] = aRadio['value'];
242 } 250 }
243 }, this)) 251 }, this))
244 252
245 updatedInputs = MochiKit.Base.concat(updatedInputs, MochiKit.Base.values(updatedRadios)); 253 updatedInputs = MochiKit.Base.concat(updatedInputs, MochiKit.Base.values(updatedRadios));
246 } 254 }
247 255
248 delete result.inputs; 256 delete result.inputs;
249 result.inputs = updatedInputs; 257 result.inputs = updatedInputs;
250//MochiKit.Logging.logDebug("<<< DirectLogin.fixFormDataFromBookmarkletVersion_0_1"); 258//MochiKit.Logging.logDebug("<<< DirectLogin.fixFormDataFromBookmarkletVersion_0_1");
251 259
252 return result; 260 return result;
253 }, 261 },
254 262
255 //......................................................................... 263 //.........................................................................
256 264
257 'directLoginInputs': function() { 265 'directLoginInputs': function() {
258 return this._directLoginInputs; 266 return this._directLoginInputs;
259 }, 267 },
260 268
261 //------------------------------------------------------------------------- 269 //-------------------------------------------------------------------------
262 270
263 'formValues': function() { 271 'formValues': function() {
264 return this._formValues; 272 return this._formValues;
265 }, 273 },
266 274
267 'hasValuesToSet': function() { 275 'hasValuesToSet': function() {
268 var result; 276 var result;
269 277
270//MochiKit.Logging.logDebug(">>> DirectLogin.hasValuesToSet"); 278//MochiKit.Logging.logDebug(">>> DirectLogin.hasValuesToSet");
271 if (this.directLoginInputs() != null) { 279 if (this.directLoginInputs() != null) {
272 result = MochiKit.Iter.some(this.directLoginInputs(), MochiKit.Base.methodcaller('shouldSetValue')); 280 result = MochiKit.Iter.some(this.directLoginInputs(), MochiKit.Base.methodcaller('shouldSetValue'));
273 } else { 281 } else {
274 result = false; 282 result = false;
275 } 283 }
276//MochiKit.Logging.logDebug("<<< DirectLogin.hasValuesToSet"); 284//MochiKit.Logging.logDebug("<<< DirectLogin.hasValuesToSet");
277 285
278 return result; 286 return result;
279 }, 287 },
280 288
281 //'additionalValues': function() { 289 //'additionalValues': function() {
282 'inputsRequiringAdditionalValues': function() { 290 'inputsRequiringAdditionalValues': function() {
283 varresult; 291 varresult;
284 var inputs; 292 var inputs;
285 293
286//MochiKit.Logging.logDebug(">>> DirectLogin.additionalValues"); 294//MochiKit.Logging.logDebug(">>> DirectLogin.additionalValues");
287 result = {}; 295 result = {};
288 if (this.directLoginInputs() != null) { 296 if (this.directLoginInputs() != null) {
289 inputs = MochiKit.Base.filter(MochiKit.Base.methodcaller('shouldSetValue'), this.directLoginInputs()); 297 inputs = MochiKit.Base.filter(MochiKit.Base.methodcaller('shouldSetValue'), this.directLoginInputs());
290 MochiKit.Iter.forEach(inputs, function(anInput) { 298 MochiKit.Iter.forEach(inputs, function(anInput) {
291 result[anInput.name()] = anInput; 299 result[anInput.name()] = anInput;
292 }) 300 })
293 } 301 }
294//MochiKit.Logging.logDebug("<<< DirectLogin.additionalValues"); 302//MochiKit.Logging.logDebug("<<< DirectLogin.additionalValues");
295 303
296 return result; 304 return result;
297 }, 305 },
298 306
299 //------------------------------------------------------------------------- 307 //-------------------------------------------------------------------------
300 308
301 'bindingData': function() { 309 'bindingData': function() {
302 return this._bindingData; 310 return this._bindingData;
303 }, 311 },
304 312
305 'setBindingData': function(aValue) { 313 'setBindingData': function(aValue) {
306//MochiKit.Logging.logDebug(">>> DirectLogin.setBindingData"); 314//MochiKit.Logging.logDebug(">>> DirectLogin.setBindingData");
307 if (aValue != null) { 315 if (aValue != null) {
308 var bindingKey; 316 var bindingKey;
309 317
310 this._bindingData = aValue; 318 this._bindingData = aValue;
311 this._bindings = {}; 319 this._bindings = {};
312 320
313 for (bindingKey in aValue) { 321 for (bindingKey in aValue) {
314 var directLoginBinding; 322 var directLoginBinding;
315 323
316 directLoginBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, bindingKey, {fieldKey:aValue[bindingKey]}); 324 directLoginBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, bindingKey, {fieldKey:aValue[bindingKey]});
317 this._bindings[bindingKey] = directLoginBinding; 325 this._bindings[bindingKey] = directLoginBinding;
318 } 326 }
319 } else { 327 } else {
320 var editableFields; 328 var editableFields;
321 var bindings; 329 var bindings;
322 330
323 bindings = {}; 331 bindings = {};
324 332
325 editableFields = MochiKit.Base.filter(function(aField) { 333 editableFields = MochiKit.Base.filter(function(aField) {
326 var result; 334 var result;
327 var type; 335 var type;
328 336
329 type = aField['type'].toLowerCase(); 337 type = aField['type'].toLowerCase();
330 result = ((type != 'hidden') && (type != 'submit') && (type != 'checkbox') && (type != 'radio') && (type != 'select')); 338 result = ((type != 'hidden') && (type != 'submit') && (type != 'checkbox') && (type != 'radio') && (type != 'select'));
331 339
332 return result; 340 return result;
333 }, this.formData().inputs); 341 }, this.formData().inputs);
334 342
335 MochiKit.Iter.forEach(editableFields, function(anEditableField) { 343 MochiKit.Iter.forEach(editableFields, function(anEditableField) {
336 bindings[anEditableField['name']] = new Clipperz.PM.DataModel.DirectLoginBinding(this, anEditableField['name']); 344 bindings[anEditableField['name']] = new Clipperz.PM.DataModel.DirectLoginBinding(this, anEditableField['name']);
337 }, this); 345 }, this);
338 346
339 this._bindings = bindings; 347 this._bindings = bindings;
340 } 348 }
341//MochiKit.Logging.logDebug("<<< DirectLogin.setBindingData"); 349//MochiKit.Logging.logDebug("<<< DirectLogin.setBindingData");
342 }, 350 },
343 351
344 'setLegacyBindingData': function(aValue) { 352 'setLegacyBindingData': function(aValue) {
345//MochiKit.Logging.logDebug(">>> DirectLogin.setLegacyBindingData"); 353//MochiKit.Logging.logDebug(">>> DirectLogin.setLegacyBindingData");
346 var bindingKey; 354 var bindingKey;
347 355
348 this._bindingData = aValue; 356 this._bindingData = aValue;
349 this._bindings = {}; 357 this._bindings = {};
350 358
351 for (bindingKey in aValue) { 359 for (bindingKey in aValue) {
352 var directLoginBinding; 360 var directLoginBinding;
353 361
354 directLoginBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, bindingKey, {fieldName:aValue[bindingKey]}); 362 directLoginBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, bindingKey, {fieldName:aValue[bindingKey]});
355 this._bindings[bindingKey] = directLoginBinding; 363 this._bindings[bindingKey] = directLoginBinding;
356 } 364 }
357//MochiKit.Logging.logDebug("<<< DirectLogin.setLegacyBindingData"); 365//MochiKit.Logging.logDebug("<<< DirectLogin.setLegacyBindingData");
358 }, 366 },
359 367
360 //......................................................................... 368 //.........................................................................
361 369
362 'bindings': function() { 370 'bindings': function() {
363 return this._bindings; 371 return this._bindings;
364 }, 372 },
365 373
366 //------------------------------------------------------------------------- 374 //-------------------------------------------------------------------------
367 375
368 'serializedData': function() { 376 'serializedData': function() {
369 var result; 377 var result;
370 varbindingKey; 378 varbindingKey;
371 379
372 result = {}; 380 result = {};
373 // result.reference = this.reference(); 381 // result.reference = this.reference();
374 result.label = this.label(); 382 result.label = this.label();
375 result.favicon = this.favicon() || ""; 383 result.favicon = this.favicon() || "";
376 result.bookmarkletVersion = this.bookmarkletVersion(); 384 result.bookmarkletVersion = this.bookmarkletVersion();
377 result.formData = this.formData(); 385 result.formData = this.formData();
378 if (this.hasValuesToSet) { 386 if (this.hasValuesToSet) {
379 result.formValues = this.formValues(); 387 result.formValues = this.formValues();
380 } 388 }
381 result.bindingData = {}; 389 result.bindingData = {};
382 390
383 for (bindingKey in this.bindings()) { 391 for (bindingKey in this.bindings()) {
384 result.bindingData[bindingKey] = this.bindings()[bindingKey].serializedData(); 392 result.bindingData[bindingKey] = this.bindings()[bindingKey].serializedData();
385 } 393 }
386 394
387 return result; 395 return result;
388 }, 396 },
389 397
390 //------------------------------------------------------------------------- 398 //-------------------------------------------------------------------------
391 399
392 'handleMissingFaviconImage': function(anEvent) { 400 'handleMissingFaviconImage': function(anEvent) {
393 anEvent.stop(); 401 anEvent.stop();
394 MochiKit.Signal.disconnectAll(anEvent.src()); 402 MochiKit.Signal.disconnectAll(anEvent.src());
395 this.setFixedFavicon(Clipperz.PM.Strings['defaultFaviconUrl']); 403 this.setFixedFavicon(Clipperz.PM.Strings['defaultFaviconUrl']);
396 anEvent.src().src = this.fixedFavicon(); 404 anEvent.src().src = this.fixedFavicon();
397 }, 405 },
398 406
399 //========================================================================= 407 //=========================================================================
400 408
401 'runHttpAuthDirectLogin': function(aWindow) { 409 'runHttpAuthDirectLogin': function(aWindow) {
402 MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() { 410 MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() {
403 var completeUrl; 411 var completeUrl;
404 var url; 412 var url;
405 413
406 url = this.bindings()['url'].field().value(); 414 url = this.bindings()['url'].field().value();
407 415
408 if (/^https?\:\/\//.test(url) == false) { 416 if (/^https?\:\/\//.test(url) == false) {
409 url = 'http://' + url; 417 url = 'http://' + url;
410 } 418 }
411 419
412 if (Clipperz_IEisBroken === true) { 420 if (Clipperz_IEisBroken === true) {
413 completeUrl = url; 421 completeUrl = url;
414 } else { 422 } else {
415 var username; 423 var username;
416 var password; 424 var password;
417 425
418 username = this.bindings()['username'].field().value(); 426 username = this.bindings()['username'].field().value();
419 password = this.bindings()['password'].field().value(); 427 password = this.bindings()['password'].field().value();
420 428
421 /(^https?\:\/\/)?(.*)/.test(url); 429 /(^https?\:\/\/)?(.*)/.test(url);
422 430
423 completeUrl = RegExp.$1 + username + ':' + password + '@' + RegExp.$2; 431 completeUrl = RegExp.$1 + username + ':' + password + '@' + RegExp.$2;
424 } 432 }
425 433
426 MochiKit.DOM.currentWindow().location.href = completeUrl; 434 MochiKit.DOM.currentWindow().location.href = completeUrl;
427 }, this)); 435 }, this));
428 }, 436 },
429 437
430 //------------------------------------------------------------------------- 438 //-------------------------------------------------------------------------
431 439
432 'runSubmitFormDirectLogin': function(aWindow) { 440 'runSubmitFormDirectLogin': function(aWindow) {
433 MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() { 441 MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() {
434 var formElement; 442 var formElement;
435 varformSubmitFunction; 443 varformSubmitFunction;
436 var submitButtons; 444 var submitButtons;
437 445
438//MochiKit.Logging.logDebug("### runDirectLogin - 3"); 446//MochiKit.Logging.logDebug("### runDirectLogin - 3");
439 // MochiKit.DOM.currentDocument().write('<html><head><title>' + this.label() + '</title><META http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body></body></html>') 447 // MochiKit.DOM.currentDocument().write('<html><head><title>' + this.label() + '</title><META http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body></body></html>')
440//MochiKit.Logging.logDebug("### runDirectLogin - 3.1"); 448//MochiKit.Logging.logDebug("### runDirectLogin - 3.1");
441 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, MochiKit.DOM.H3(null, "Loading " + this.label() + " ...")); 449 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, MochiKit.DOM.H3(null, "Loading " + this.label() + " ..."));
442//MochiKit.Logging.logDebug("### runDirectLogin - 4"); 450//MochiKit.Logging.logDebug("### runDirectLogin - 4");
443//console.log(this.formData()['attributes']); 451//console.log(this.formData()['attributes']);
444 formElement = MochiKit.DOM.FORM(MochiKit.Base.update({id:'directLoginForm'}, {'method':this.formData()['attributes']['method'], 452 formElement = MochiKit.DOM.FORM(MochiKit.Base.update({id:'directLoginForm'}, {'method':this.formData()['attributes']['method'],
445 'action':this.formData()['attributes']['action']})); 453 'action': this.action()}));
446//MochiKit.Logging.logDebug("### runDirectLogin - 5"); 454//MochiKit.Logging.logDebug("### runDirectLogin - 5");
447 formSubmitFunction = MochiKit.Base.method(formElement, 'submit'); 455 formSubmitFunction = MochiKit.Base.method(formElement, 'submit');
448//MochiKit.Logging.logDebug("### runDirectLogin - 6"); 456//MochiKit.Logging.logDebug("### runDirectLogin - 6");
449 457
450 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, 458 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body,
451 MochiKit.DOM.DIV({style:'display:none; visibility:hidden;'}, formElement) 459 MochiKit.DOM.DIV({style:'display:none; visibility:hidden;'}, formElement)
452 ); 460 );
453//MochiKit.Logging.logDebug("### runDirectLogin - 7"); 461//MochiKit.Logging.logDebug("### runDirectLogin - 7");
454 MochiKit.DOM.appendChildNodes(formElement, MochiKit.Base.map(MochiKit.Base.methodcaller("formConfiguration"), 462 MochiKit.DOM.appendChildNodes(formElement, MochiKit.Base.map(MochiKit.Base.methodcaller("formConfiguration"),
455 this.directLoginInputs())); 463 this.directLoginInputs()));
456//MochiKit.Logging.logDebug("### runDirectLogin - 8"); 464//MochiKit.Logging.logDebug("### runDirectLogin - 8");
457 465
458 submitButtons = MochiKit.Base.filter(function(anInputElement) { 466 submitButtons = MochiKit.Base.filter(function(anInputElement) {
459//MochiKit.Logging.logDebug("### runDirectLogin - 8.1 - " + anInputElement); 467//MochiKit.Logging.logDebug("### runDirectLogin - 8.1 - " + anInputElement);
460//MochiKit.Logging.logDebug("### runDirectLogin - 8.2 - " + anInputElement.tagName); 468//MochiKit.Logging.logDebug("### runDirectLogin - 8.2 - " + anInputElement.tagName);
461//MochiKit.Logging.logDebug("### runDirectLogin - 8.3 - " + anInputElement.getAttribute('type')); 469//MochiKit.Logging.logDebug("### runDirectLogin - 8.3 - " + anInputElement.getAttribute('type'));
462 return ((anInputElement.tagName.toLowerCase() == 'input') && (anInputElement.getAttribute('type').toLowerCase() == 'submit')); 470 return ((anInputElement.tagName.toLowerCase() == 'input') && (anInputElement.getAttribute('type').toLowerCase() == 'submit'));
463 }, formElement.elements) 471 }, formElement.elements)
464//MochiKit.Logging.logDebug("### runDirectLogin - 9"); 472//MochiKit.Logging.logDebug("### runDirectLogin - 9");
465 473
466 if (submitButtons.length == 0) { 474 if (submitButtons.length == 0) {
467//MochiKit.Logging.logDebug("### OLD submit") 475//MochiKit.Logging.logDebug("### OLD submit")
468 if (Clipperz_IEisBroken == true) { 476 if (Clipperz_IEisBroken == true) {
469//MochiKit.Logging.logDebug("### runDirectLogin - 10"); 477//MochiKit.Logging.logDebug("### runDirectLogin - 10");
470 formElement.submit(); 478 formElement.submit();
471 } else { 479 } else {
472//MochiKit.Logging.logDebug("### runDirectLogin - 11"); 480//MochiKit.Logging.logDebug("### runDirectLogin - 11");
473 formSubmitFunction(); 481 formSubmitFunction();
474 } 482 }
475 } else { 483 } else {
476//MochiKit.Logging.logDebug("### NEW submit") 484//MochiKit.Logging.logDebug("### NEW submit")
477 submitButtons[0].click(); 485 submitButtons[0].click();
478 } 486 }
479 487
480 }, this)); 488 }, this));
481 }, 489 },
482 490
483 //------------------------------------------------------------------------- 491 //-------------------------------------------------------------------------
484 492
485 'runDirectLogin': function(aNewWindow) { 493 'runDirectLogin': function(aNewWindow) {
486 varnewWindow; 494 varnewWindow;
487 495
488//console.log("formData.attributes", this.formData()['attributes']); 496//console.log("formData.attributes", this.formData()['attributes']);
489 // if (/^javascript/.test(this.formData()['attributes']['action'])) { 497 // if (/^javascript/.test(this.formData()['attributes']['action'])) {
490 if ((/^(https?|webdav|ftp)\:/.test(this.formData()['attributes']['action']) == false) && 498 if ((/^(https?|webdav|ftp)\:/.test(this.action()) == false) &&
491 (this.formData()['attributes']['type'] != 'http_auth')) 499 (this.formData()['attributes']['type'] != 'http_auth')
492 { 500 ) {
493 var messageBoxConfiguration; 501 var messageBoxConfiguration;
494 502
495 if (typeof(aNewWindow) != 'undefined') { 503 if (typeof(aNewWindow) != 'undefined') {
496 aNewWindow.close(); 504 aNewWindow.close();
497 } 505 }
498 506
499 messageBoxConfiguration = {}; 507 messageBoxConfiguration = {};
500 messageBoxConfiguration.title = Clipperz.PM.Strings['VulnerabilityWarning_Panel_title']; 508 messageBoxConfiguration.title = Clipperz.PM.Strings['VulnerabilityWarning_Panel_title'];
501 messageBoxConfiguration.msg = Clipperz.PM.Strings['VulnerabilityWarning_Panel_message']; 509 messageBoxConfiguration.msg = Clipperz.PM.Strings['VulnerabilityWarning_Panel_message'];
502 messageBoxConfiguration.animEl = YAHOO.ext.Element.get("mainDiv"); 510 messageBoxConfiguration.animEl = YAHOO.ext.Element.get("mainDiv");
503 messageBoxConfiguration.progress = false; 511 messageBoxConfiguration.progress = false;
504 messageBoxConfiguration.closable = false; 512 messageBoxConfiguration.closable = false;
505 messageBoxConfiguration.buttons = {'cancel': Clipperz.PM.Strings['VulnerabilityWarning_Panel_buttonLabel']}; 513 messageBoxConfiguration.buttons = {'cancel': Clipperz.PM.Strings['VulnerabilityWarning_Panel_buttonLabel']};
506 514
507 Clipperz.YUI.MessageBox.show(messageBoxConfiguration); 515 Clipperz.YUI.MessageBox.show(messageBoxConfiguration);
508 516
509 throw Clipperz.Base.exception.VulnerabilityIssue; 517 throw Clipperz.Base.exception.VulnerabilityIssue;
510 } 518 }
511 519
512//MochiKit.Logging.logDebug("### runDirectLogin - 1 : " + Clipperz.Base.serializeJSON(this.serializedData())); 520//MochiKit.Logging.logDebug("### runDirectLogin - 1 : " + Clipperz.Base.serializeJSON(this.serializedData()));
513 if (typeof(aNewWindow) == 'undefined') { 521 if (typeof(aNewWindow) == 'undefined') {
514 newWindow = window.open(Clipperz.PM.Strings['directLoginJumpPageUrl'], ""); 522 newWindow = window.open(Clipperz.PM.Strings['directLoginJumpPageUrl'], "");
515 } else { 523 } else {
516 newWindow = aNewWindow; 524 newWindow = aNewWindow;
517 } 525 }
518//MochiKit.Logging.logDebug("### runDirectLogin - 2"); 526//MochiKit.Logging.logDebug("### runDirectLogin - 2");
519 527
520 if (this.formData()['attributes']['type'] == 'http_auth') { 528 if (this.formData()['attributes']['type'] == 'http_auth') {
521 this.runHttpAuthDirectLogin(newWindow); 529 this.runHttpAuthDirectLogin(newWindow);
522 } else { 530 } else {
523 this.runSubmitFormDirectLogin(newWindow) 531 this.runSubmitFormDirectLogin(newWindow)
524 } 532 }
525 }, 533 },
526 534
527 //------------------------------------------------------------------------- 535 //-------------------------------------------------------------------------
528 __syntaxFix__: "syntax fix" 536 __syntaxFix__: "syntax fix"
529 537
530}); 538});
531 539
diff --git a/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js b/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js
index 236d7c9..ba302da 100644
--- a/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js
+++ b/frontend/beta/js/Clipperz/PM/DataModel/DirectLoginReference.js
@@ -1,187 +1,187 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } 24if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } 25if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
26if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; } 26if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
27 27
28 28
29//############################################################################# 29//#############################################################################
30 30
31Clipperz.PM.DataModel.DirectLoginReference = function(args) { 31Clipperz.PM.DataModel.DirectLoginReference = function(args) {
32 args = args || {}; 32 args = args || {};
33 33
34//MochiKit.Logging.logDebug(">>> new DirectLoginReference: " + Clipperz.Base.serializeJSON(MochiKit.Base.keys(args))); 34//MochiKit.Logging.logDebug(">>> new DirectLoginReference: " + Clipperz.Base.serializeJSON(MochiKit.Base.keys(args)));
35//MochiKit.Logging.logDebug(">>> new DirectLoginReference - record: " + args.record); 35//MochiKit.Logging.logDebug(">>> new DirectLoginReference - record: " + args.record);
36 this._user = args.user; 36 this._user = args.user;
37 37
38 if (args.directLogin != null) { 38 if (args.directLogin != null) {
39 this._reference = args.directLogin.reference(); 39 this._reference = args.directLogin.reference();
40 this._recordReference = args.directLogin.record().reference(); 40 this._recordReference = args.directLogin.record().reference();
41 this._label = args.directLogin.label(); 41 this._label = args.directLogin.label();
42 this._favicon = args.directLogin.favicon() || null; 42 this._favicon = args.directLogin.favicon() || null;
43 43
44 this._directLogin = args.directLogin; 44 this._directLogin = args.directLogin;
45 this._record = args.directLogin.record(); 45 this._record = args.directLogin.record();
46 } else { 46 } else {
47 this._reference = args.reference; 47 this._reference = args.reference;
48 this._recordReference = args.record; 48 this._recordReference = args.record;
49 this._label = args.label; 49 this._label = args.label;
50 this._favicon = args.favicon || null; 50 this._favicon = Clipperz.Base.sanitizeFavicon(args.favicon) || null;
51 51
52 this._directLogin = null; 52 this._directLogin = null;
53 this._record = null; 53 this._record = null;
54 } 54 }
55 55
56 this._fixedFavicon = null; 56 this._fixedFavicon = null;
57 57
58 return this; 58 return this;
59} 59}
60 60
61Clipperz.PM.DataModel.DirectLoginReference.prototype = MochiKit.Base.update(null, { 61Clipperz.PM.DataModel.DirectLoginReference.prototype = MochiKit.Base.update(null, {
62 62
63 'user': function() { 63 'user': function() {
64 return this._user; 64 return this._user;
65 }, 65 },
66 66
67 //------------------------------------------------------------------------- 67 //-------------------------------------------------------------------------
68 68
69 'reference': function() { 69 'reference': function() {
70 return this._reference; 70 return this._reference;
71 }, 71 },
72 72
73 //------------------------------------------------------------------------- 73 //-------------------------------------------------------------------------
74 74
75 'synchronizeValues': function(aDirectLogin) { 75 'synchronizeValues': function(aDirectLogin) {
76 this._label = aDirectLogin.label(); 76 this._label = aDirectLogin.label();
77 this._favicon = aDirectLogin.favicon(); 77 this._favicon = aDirectLogin.favicon();
78 }, 78 },
79 79
80 //------------------------------------------------------------------------- 80 //-------------------------------------------------------------------------
81 81
82 'label': function() { 82 'label': function() {
83 return this._label; 83 return this._label;
84 }, 84 },
85 85
86 //------------------------------------------------------------------------- 86 //-------------------------------------------------------------------------
87 87
88 'recordReference': function() { 88 'recordReference': function() {
89 return this._recordReference; 89 return this._recordReference;
90 }, 90 },
91 91
92 //------------------------------------------------------------------------- 92 //-------------------------------------------------------------------------
93 93
94 'record': function() { 94 'record': function() {
95//MochiKit.Logging.logDebug(">>> DirectLoginReference.record"); 95//MochiKit.Logging.logDebug(">>> DirectLoginReference.record");
96 if (this._record == null) { 96 if (this._record == null) {
97 this._record = this.user().records()[this.recordReference()]; 97 this._record = this.user().records()[this.recordReference()];
98 } 98 }
99 99
100//MochiKit.Logging.logDebug("<<< DirectLoginReference.record"); 100//MochiKit.Logging.logDebug("<<< DirectLoginReference.record");
101 return this._record; 101 return this._record;
102 }, 102 },
103 103
104 //------------------------------------------------------------------------- 104 //-------------------------------------------------------------------------
105 105
106 'favicon': function() { 106 'favicon': function() {
107 return this._favicon; 107 return this._favicon;
108 }, 108 },
109 109
110 //------------------------------------------------------------------------- 110 //-------------------------------------------------------------------------
111 111
112 'fixedFavicon': function() { 112 'fixedFavicon': function() {
113 var result; 113 var result;
114 114
115 if (this._fixedFavicon == null) { 115 if (this._fixedFavicon == null) {
116 result = this.favicon(); 116 result = this.favicon();
117 117
118 if (Clipperz_IEisBroken && (this.user().preferences().disableUnsecureFaviconLoadingForIE()) && (result.indexOf('https://') != 0)) { 118 if (Clipperz_IEisBroken && (this.user().preferences().disableUnsecureFaviconLoadingForIE()) && (result.indexOf('https://') != 0)) {
119 result = Clipperz.PM.Strings['defaultFaviconUrl_IE']; 119 result = Clipperz.PM.Strings['defaultFaviconUrl_IE'];
120 this.setFixedFavicon(result); 120 this.setFixedFavicon(result);
121 } 121 }
122 } else { 122 } else {
123 result = this._fixedFavicon; 123 result = this._fixedFavicon;
124 } 124 }
125 125
126 return result; 126 return result;
127 }, 127 },
128 128
129 'setFixedFavicon': function(aValue) { 129 'setFixedFavicon': function(aValue) {
130 this._fixedFavicon = aValue; 130 this._fixedFavicon = aValue;
131 }, 131 },
132 132
133 //------------------------------------------------------------------------- 133 //-------------------------------------------------------------------------
134 134
135 'setupJumpPageWindow': function(aWindow) { 135 'setupJumpPageWindow': function(aWindow) {
136//MochiKit.Logging.logDebug(">>> DirectLoginReference.setupJumpPageWindow - " + aWindow); 136//MochiKit.Logging.logDebug(">>> DirectLoginReference.setupJumpPageWindow - " + aWindow);
137 try { 137 try {
138 MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() { 138 MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function() {
139 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, 139 MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body,
140 MochiKit.DOM.H1(null, "Loading " + this.label()) 140 MochiKit.DOM.H1(null, "Loading " + this.label())
141 ); 141 );
142 }, this)); 142 }, this));
143 } catch(e) { 143 } catch(e) {
144 MochiKit.Logging.logDebug("EXCEPTION: " + e); 144 MochiKit.Logging.logDebug("EXCEPTION: " + e);
145 } 145 }
146//MochiKit.Logging.logDebug("<<< DirectLoginReference.setupJumpPageWindow"); 146//MochiKit.Logging.logDebug("<<< DirectLoginReference.setupJumpPageWindow");
147 }, 147 },
148 148
149 //------------------------------------------------------------------------- 149 //-------------------------------------------------------------------------
150 150
151 'deferredDirectLogin': function() { 151 'deferredDirectLogin': function() {
152 var deferredResult; 152 var deferredResult;
153 153
154//MochiKit.Logging.logDebug(">>> DirectLoginReference.deferredDirectLogin - " + this); 154//MochiKit.Logging.logDebug(">>> DirectLoginReference.deferredDirectLogin - " + this);
155 deferredResult = new MochiKit.Async.Deferred(); 155 deferredResult = new MochiKit.Async.Deferred();
156//MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 1"); 156//MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 1");
157 deferredResult.addCallback(MochiKit.Base.method(this.record(), 'deferredData')); 157 deferredResult.addCallback(MochiKit.Base.method(this.record(), 'deferredData'));
158//MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 2"); 158//MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 2");
159 deferredResult.addCallback(function(aRecord, aDirectLoginReference) { 159 deferredResult.addCallback(function(aRecord, aDirectLoginReference) {
160 return aRecord.directLogins()[aDirectLoginReference]; 160 return aRecord.directLogins()[aDirectLoginReference];
161 }, this.record(), this.reference()); 161 }, this.record(), this.reference());
162//MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 3"); 162//MochiKit.Logging.logDebug("--- DirectLoginReference.deferredDirectLogin - 3");
163 deferredResult.callback(); 163 deferredResult.callback();
164//MochiKit.Logging.logDebug("<<< DirectLoginReference.deferredDirectLogin"); 164//MochiKit.Logging.logDebug("<<< DirectLoginReference.deferredDirectLogin");
165 165
166 return deferredResult; 166 return deferredResult;
167 }, 167 },
168 168
169 //------------------------------------------------------------------------- 169 //-------------------------------------------------------------------------
170 170
171 'handleMissingFaviconImage': function(anEvent) { 171 'handleMissingFaviconImage': function(anEvent) {
172//MochiKit.Logging.logDebug(">>> DirectLoginReference.handleMissingFaviconImage"); 172//MochiKit.Logging.logDebug(">>> DirectLoginReference.handleMissingFaviconImage");
173 anEvent.stop(); 173 anEvent.stop();
174 MochiKit.Signal.disconnectAll(anEvent.src()); 174 MochiKit.Signal.disconnectAll(anEvent.src());
175 this.setFixedFavicon(Clipperz.PM.Strings['defaultFaviconUrl']); 175 this.setFixedFavicon(Clipperz.PM.Strings['defaultFaviconUrl']);
176//MochiKit.Logging.logDebug("--- DirectLoginReference.handleMissingFaviconImage - fixedFavicon: " + this.fixedFavicon()); 176//MochiKit.Logging.logDebug("--- DirectLoginReference.handleMissingFaviconImage - fixedFavicon: " + this.fixedFavicon());
177//MochiKit.Logging.logDebug("--- DirectLoginReference.handleMissingFaviconImage - anEvent.src().src: " + anEvent.src().src); 177//MochiKit.Logging.logDebug("--- DirectLoginReference.handleMissingFaviconImage - anEvent.src().src: " + anEvent.src().src);
178 // MochiKit.DOM.swapDOM(anEvent.src(), MochiKit.DOM.IMG({src:'this.fixedFavicon()'})); 178 // MochiKit.DOM.swapDOM(anEvent.src(), MochiKit.DOM.IMG({src:'this.fixedFavicon()'}));
179 anEvent.src().src = this.fixedFavicon(); 179 anEvent.src().src = this.fixedFavicon();
180//MochiKit.Logging.logDebug("<<< DirectLoginReference.handleMissingFaviconImage"); 180//MochiKit.Logging.logDebug("<<< DirectLoginReference.handleMissingFaviconImage");
181 }, 181 },
182 182
183 //------------------------------------------------------------------------- 183 //-------------------------------------------------------------------------
184 __syntaxFix__: "syntax fix" 184 __syntaxFix__: "syntax fix"
185 185
186}); 186});
187 187
diff --git a/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js b/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
index 1a5caff..b0b9b63 100644
--- a/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
+++ b/frontend/beta/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
@@ -1,560 +1,587 @@
1/* 1/*
2 2
3Copyright 2008-2013 Clipperz Srl 3Copyright 2008-2013 Clipperz Srl
4 4
5This file is part of Clipperz, the online password manager. 5This file is part of Clipperz, the online password manager.
6For further information about its features and functionalities please 6For further information about its features and functionalities please
7refer to http://www.clipperz.com. 7refer to http://www.clipperz.com.
8 8
9* Clipperz is free software: you can redistribute it and/or modify it 9* Clipperz is free software: you can redistribute it and/or modify it
10 under the terms of the GNU Affero General Public License as published 10 under the terms of the GNU Affero General Public License as published
11 by the Free Software Foundation, either version 3 of the License, or 11 by the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version. 12 (at your option) any later version.
13 13
14* Clipperz is distributed in the hope that it will be useful, but 14* Clipperz is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU Affero General Public License for more details. 17 See the GNU Affero General Public License for more details.
18 18
19* You should have received a copy of the GNU Affero General Public 19* You should have received a copy of the GNU Affero General Public
20 License along with Clipperz. If not, see http://www.gnu.org/licenses/. 20 License along with Clipperz. If not, see http://www.gnu.org/licenses/.
21 21
22*/ 22*/
23 23
24try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) { 24try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) {
25 throw "Clipperz.PM.Proxy.Offline.DataStore depends on Clipperz.PM.Proxy.Offline!"; 25 throw "Clipperz.PM.Proxy.Offline.DataStore depends on Clipperz.PM.Proxy.Offline!";
26} 26}
27 27
28//============================================================================= 28//=============================================================================
29 29
30Clipperz.PM.Proxy.Offline.DataStore = function(args) { 30Clipperz.PM.Proxy.Offline.DataStore = function(args) {
31 args = args || {}; 31 args = args || {};
32 32
33 this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null); 33 this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null);
34 this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly); 34 this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly);
35 this._shouldPayTolls = args.shouldPayTolls || false; 35 this._shouldPayTolls = args.shouldPayTolls || false;
36 36
37 this._tolls = {}; 37 this._tolls = {};
38 this._connections = {}; 38 this._connections = {};
39 39
40 this._C = null;
40 this._b = null; 41 this._b = null;
41 this._B = null; 42 this._B = null;
42 this._A = null; 43 this._A = null;
43 this._userData = null; 44 this._userData = null;
44 45
45 return this; 46 return this;
46} 47}
47 48
48//Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, { 49//Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
49Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, { 50Clipperz.PM.Proxy.Offline.DataStore.prototype = MochiKit.Base.update(null, {
50 51
51 //------------------------------------------------------------------------- 52 //-------------------------------------------------------------------------
52 53
53 'isReadOnly': function () { 54 'isReadOnly': function () {
54 return this._isReadOnly; 55 return this._isReadOnly;
55 }, 56 },
56 57
57 //------------------------------------------------------------------------- 58 //-------------------------------------------------------------------------
58 59
59 'shouldPayTolls': function() { 60 'shouldPayTolls': function() {
60 return this._shouldPayTolls; 61 return this._shouldPayTolls;
61 }, 62 },
62 63
63 //------------------------------------------------------------------------- 64 //-------------------------------------------------------------------------
64 65
65 'data': function () { 66 'data': function () {
66 return this._data; 67 return this._data;
67 }, 68 },
68 69
69 //------------------------------------------------------------------------- 70 //-------------------------------------------------------------------------
70 71
71 'tolls': function () { 72 'tolls': function () {
72 return this._tolls; 73 return this._tolls;
73 }, 74 },
74 75
75 //------------------------------------------------------------------------- 76 //-------------------------------------------------------------------------
76 77
77 'connections': function () { 78 'connections': function () {
78 return this._connections; 79 return this._connections;
79 }, 80 },
80 81
81 //========================================================================= 82 //=========================================================================
82 83
83 'resetData': function() { 84 'resetData': function() {
84 this._data = { 85 this._data = {
85 'users': { 86 'users': {
86 'catchAllUser': { 87 'catchAllUser': {
87 __masterkey_test_value__: 'masterkey', 88 __masterkey_test_value__: 'masterkey',
88 s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00', 89 s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
89 v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00' 90 v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
90 } 91 }
91 } 92 }
92 }; 93 };
93 }, 94 },
94 95
95 //------------------------------------------------------------------------- 96 //-------------------------------------------------------------------------
96 97
97 'setupWithEncryptedData': function(someData) { 98 'setupWithEncryptedData': function(someData) {
98 this._data = Clipperz.Base.deepClone(someData); 99 this._data = Clipperz.Base.deepClone(someData);
99 }, 100 },
100 101
101 //------------------------------------------------------------------------- 102 //-------------------------------------------------------------------------
102 103
103 'setupWithData': function(someData) { 104 'setupWithData': function(someData) {
104 var deferredResult; 105 var deferredResult;
105 var resultData; 106 var resultData;
106 var i, c; 107 var i, c;
107 108
108//Clipperz.log(">>> Proxy.Test.setupWithData"); 109//Clipperz.log(">>> Proxy.Test.setupWithData");
109 resultData = this._data; 110 resultData = this._data;
110 111
111 deferredResult = new MochiKit.Async.Deferred(); 112 deferredResult = new MochiKit.Async.Deferred();
112 c = someData['users'].length; 113 c = someData['users'].length;
113 114
114 for (i=0; i<c; i++) { 115 for (i=0; i<c; i++) {
115 varnewConnection; 116 varnewConnection;
116 varrecordConfiguration; 117 varrecordConfiguration;
117 118
118 deferredResult.addCallback(MochiKit.Base.method(this, 'userSerializedEncryptedData', someData['users'][i])); 119 deferredResult.addCallback(MochiKit.Base.method(this, 'userSerializedEncryptedData', someData['users'][i]));
119 deferredResult.addCallback(MochiKit.Base.bind(function(aUserSerializationContext) { 120 deferredResult.addCallback(MochiKit.Base.bind(function(aUserSerializationContext) {
120//console.log("SERIALIZED USER", aUserSerializationContext); 121//console.log("SERIALIZED USER", aUserSerializationContext);
121 resultData['users'][aUserSerializationContext['credentials']['C']] = { 122 resultData['users'][aUserSerializationContext['credentials']['C']] = {
122 's': aUserSerializationContext['credentials']['s'], 123 's': aUserSerializationContext['credentials']['s'],
123 'v': aUserSerializationContext['credentials']['v'], 124 'v': aUserSerializationContext['credentials']['v'],
124 'version': aUserSerializationContext['data']['connectionVersion'], 125 'version': aUserSerializationContext['data']['connectionVersion'],
125 'userDetails': aUserSerializationContext['encryptedData']['user']['header'], 126 'userDetails': aUserSerializationContext['encryptedData']['user']['header'],
126 'userDetailsVersion':aUserSerializationContext['encryptedData']['user']['version'], 127 'userDetailsVersion':aUserSerializationContext['encryptedData']['user']['version'],
127 'statistics': aUserSerializationContext['encryptedData']['user']['statistics'], 128 'statistics': aUserSerializationContext['encryptedData']['user']['statistics'],
128 'lock': aUserSerializationContext['encryptedData']['user']['lock'], 129 'lock': aUserSerializationContext['encryptedData']['user']['lock'],
129 'records': this.rearrangeRecordsData(aUserSerializationContext['encryptedData']['records']) 130 'records': this.rearrangeRecordsData(aUserSerializationContext['encryptedData']['records'])
130 } 131 }
131 }, this)); 132 }, this));
132 } 133 }
133 134
134 deferredResult.addCallback(MochiKit.Base.bind(function() { 135 deferredResult.addCallback(MochiKit.Base.bind(function() {
135//console.log("this._data", resultData); 136//console.log("this._data", resultData);
136 this._data = resultData; 137 this._data = resultData;
137 }, this)); 138 }, this));
138 139
139 deferredResult.callback(); 140 deferredResult.callback();
140//Clipperz.log("<<< Proxy.Test.setupWithData"); 141//Clipperz.log("<<< Proxy.Test.setupWithData");
141 142
142 return deferredResult; 143 return deferredResult;
143 }, 144 },
144 145
145 //========================================================================= 146 //=========================================================================
146 147
148 'C': function() {
149 return this._C;
150 },
151
152 'set_C': function(aValue) {
153 this._C = aValue;
154 },
155
156 //-------------------------------------------------------------------------
157
147 'b': function() { 158 'b': function() {
148 return this._b; 159 return this._b;
149 }, 160 },
150 161
151 'set_b': function(aValue) { 162 'set_b': function(aValue) {
152 this._b = aValue; 163 this._b = aValue;
153 }, 164 },
154 165
155 //------------------------------------------------------------------------- 166 //-------------------------------------------------------------------------
156 167
157 'B': function() { 168 'B': function() {
158 return this._B; 169 return this._B;
159 }, 170 },
160 171
161 'set_B': function(aValue) { 172 'set_B': function(aValue) {
162 this._B = aValue; 173 this._B = aValue;
163 }, 174 },
164 175
165 //------------------------------------------------------------------------- 176 //-------------------------------------------------------------------------
166 177
167 'A': function() { 178 'A': function() {
168 return this._A; 179 return this._A;
169 }, 180 },
170 181
171 'set_A': function(aValue) { 182 'set_A': function(aValue) {
172 this._A = aValue; 183 this._A = aValue;
173 }, 184 },
174 185
175 //------------------------------------------------------------------------- 186 //-------------------------------------------------------------------------
176 187
177 'userData': function() { 188 'userData': function() {
178 return this._userData; 189 return this._userData;
179 }, 190 },
180 191
181 'setUserData': function(aValue) { 192 'setUserData': function(aValue) {
182 this._userData = aValue; 193 this._userData = aValue;
183 }, 194 },
184 195
185 //========================================================================= 196 //=========================================================================
186 197
187 'getTollForRequestType': function (aRequestType) { 198 'getTollForRequestType': function (aRequestType) {
188 varresult; 199 varresult;
189 vartargetValue; 200 vartargetValue;
190 var cost; 201 var cost;
191 202
192 targetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2); 203 targetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
193 switch (aRequestType) { 204 switch (aRequestType) {
194 case 'REGISTER': 205 case 'REGISTER':
195 cost = 5; 206 cost = 5;
196 break; 207 break;
197 case 'CONNECT': 208 case 'CONNECT':
198 cost = 5; 209 cost = 5;
199 break; 210 break;
200 case 'MESSAGE': 211 case 'MESSAGE':
201 cost = 2; 212 cost = 2;
202 break; 213 break;
203 } 214 }
204 215
205 result = { 216 result = {
206 requestType: aRequestType, 217 requestType: aRequestType,
207 targetValue: targetValue, 218 targetValue: targetValue,
208 cost: cost 219 cost: cost
209 } 220 }
210 221
211 if (this.shouldPayTolls()) { 222 if (this.shouldPayTolls()) {
212 this.tolls()[targetValue] = result; 223 this.tolls()[targetValue] = result;
213 } 224 }
214 225
215 return result; 226 return result;
216 }, 227 },
217 228
218 //------------------------------------------------------------------------- 229 //-------------------------------------------------------------------------
219 230
220 'checkToll': function (aFunctionName, someParameters) { 231 'checkToll': function (aFunctionName, someParameters) {
221 if (this.shouldPayTolls()) { 232 if (this.shouldPayTolls()) {
222 var localToll; 233 var localToll;
223 vartollParameters; 234 vartollParameters;
224 235
225 tollParameters = someParameters['toll']; 236 tollParameters = someParameters['toll'];
226 localToll = this.tolls()[tollParameters['targetValue']]; 237 localToll = this.tolls()[tollParameters['targetValue']];
227 238
228 if (localToll != null) { 239 if (localToll != null) {
229 if (! Clipperz.PM.Toll.validate(tollParameters['targetValue'], tollParameters['toll'], localToll['cost'])) { 240 if (! Clipperz.PM.Toll.validate(tollParameters['targetValue'], tollParameters['toll'], localToll['cost'])) {
230 throw "Toll value too low."; 241 throw "Toll value too low.";
231 }; 242 };
232 } else { 243 } else {
233 throw "Missing toll"; 244 throw "Missing toll";
234 } 245 }
235 } 246 }
236 }, 247 },
237 248
238 //========================================================================= 249 //=========================================================================
239 250
240 'processMessage': function(aFunctionName, someParameters) { 251 'processMessage': function (aFunctionName, someParameters) {
241 var result; 252 var result;
242 253
243 switch(aFunctionName) { 254 switch(aFunctionName) {
244 case 'knock': 255 case 'knock':
245 result = this._knock(someParameters); 256 result = this._knock(someParameters);
246 break; 257 break;
247 case 'registration': 258 case 'registration':
248 this.checkToll(aFunctionName, someParameters); 259 this.checkToll(aFunctionName, someParameters);
249 result = this._registration(someParameters.parameters); 260 result = this._registration(someParameters.parameters);
250 break; 261 break;
251 case 'handshake': 262 case 'handshake':
252 this.checkToll(aFunctionName, someParameters); 263 this.checkToll(aFunctionName, someParameters);
253 result = this._handshake(someParameters.parameters); 264 result = this._handshake(someParameters.parameters);
254 break; 265 break;
255 case 'message': 266 case 'message':
256 this.checkToll(aFunctionName, someParameters); 267 this.checkToll(aFunctionName, someParameters);
257 result = this._message(someParameters.parameters); 268 result = this._message(someParameters.parameters);
258 break; 269 break;
259 case 'logout': 270 case 'logout':
260 result = this._logout(someParameters.parameters); 271 result = this._logout(someParameters.parameters);
261 break; 272 break;
262 } 273 }
263 274
264 return result; 275 return result;
265 }, 276 },
266 277
267 //========================================================================= 278 //=========================================================================
268 279
269 '_knock': function(someParameters) { 280 '_knock': function(someParameters) {
270 var result; 281 var result;
271 282
272 result = { 283 result = {
273 toll: this.getTollForRequestType(someParameters['requestType']) 284 toll: this.getTollForRequestType(someParameters['requestType'])
274 // toll: { 285 // toll: {
275 // requestType: someParameters['requestType'], 286 // requestType: someParameters['requestType'],
276 // targetValue: "3a1ba0be23580f902885c6c8a6b035e228ed1ca74d77de5f9bb0e0c899f07cfe", 287 // targetValue: "3a1ba0be23580f902885c6c8a6b035e228ed1ca74d77de5f9bb0e0c899f07cfe",
277 // cost: 288 // cost:
278 // } 289 // }
279 } 290 }
280 291
281 return result; 292 return result;
282 }, 293 },
283 294
284 //------------------------------------------------------------------------- 295 //-------------------------------------------------------------------------
285 296
286 '_registration': function(someParameters) { 297 '_registration': function(someParameters) {
287//console.log("_registration", someParameters); 298//console.log("_registration", someParameters);
288 if (this.isReadOnly() == false) { 299 if (this.isReadOnly() == false) {
289 if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') { 300 if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') {
290 this.data()['users'][someParameters['credentials']['C']] = { 301 this.data()['users'][someParameters['credentials']['C']] = {
291 's': someParameters['credentials']['s'], 302 's': someParameters['credentials']['s'],
292 'v': someParameters['credentials']['v'], 303 'v': someParameters['credentials']['v'],
293 'version':someParameters['credentials']['version'], 304 'version':someParameters['credentials']['version'],
294 // 'lock': someParameters['user']['lock'], 305 // 'lock': someParameters['user']['lock'],
295 'lock': Clipperz.Crypto.Base.generateRandomSeed(), 306 'lock': Clipperz.Crypto.Base.generateRandomSeed(),
296 // 'maxNumberOfRecords':'100', 307 // 'maxNumberOfRecords':'100',
297 'userDetails': someParameters['user']['header'], 308 'userDetails': someParameters['user']['header'],
298 'statistics': someParameters['user']['statistics'], 309 'statistics': someParameters['user']['statistics'],
299 'userDetailsVersion':someParameters['user']['version'], 310 'userDetailsVersion':someParameters['user']['version'],
300 'records':{} 311 'records':{}
301 } 312 }
302 } else { 313 } else {
303 throw "user already exists"; 314 throw "user already exists";
304 } 315 }
305 } else { 316 } else {
306 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 317 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
307 } 318 }
308 319
309 result = { 320 result = {
310 result: { 321 result: {
311 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'], 322 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'],
312 'result':'done' 323 'result':'done'
313 }, 324 },
314 toll: this.getTollForRequestType('CONNECT') 325 toll: this.getTollForRequestType('CONNECT')
315 } 326 }
316 327
317 return MochiKit.Async.succeed(result); 328 return MochiKit.Async.succeed(result);
318 }, 329 },
319 330
320 //------------------------------------------------------------------------- 331 //-------------------------------------------------------------------------
321 332
322 '_handshake': function(someParameters) { 333 '_handshake': function(someParameters) {
323 var result; 334 var result;
324 varnextTollRequestType; 335 varnextTollRequestType;
325 336
326//Clipperz.log(">>> Proxy.Offline.DataStore._handshake"); 337//Clipperz.log(">>> Proxy.Offline.DataStore._handshake");
327 result = {}; 338 result = {};
328 if (someParameters.message == "connect") { 339 if (someParameters.message == "connect") {
329 var userData; 340 var userData;
330 var randomBytes; 341 var randomBytes;
331 var b, B, v; 342 var b, B, v;
332 343
333//console.log(">>> Proxy.Offline.DataStore._handshake.connect", someParameters); 344//console.log(">>> Proxy.Offline.DataStore._handshake.connect", someParameters);
334 userData = this.data()['users'][someParameters.parameters.C]; 345 userData = this.data()['users'][someParameters.parameters.C];
335 346
336 if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) { 347 if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) {
337 this.setUserData(userData); 348 this.setUserData(userData);
338 } else { 349 } else {
339 this.setUserData(this.data()['users']['catchAllUser']); 350 this.setUserData(this.data()['users']['catchAllUser']);
340 } 351 }
341 352
342 randomBytes = Clipperz.Crypto.Base.generateRandomSeed(); 353 randomBytes = Clipperz.Crypto.Base.generateRandomSeed();
354 this.set_C(someParameters.parameters.C);
343 this.set_b(new Clipperz.Crypto.BigInt(randomBytes, 16)); 355 this.set_b(new Clipperz.Crypto.BigInt(randomBytes, 16));
344 v = new Clipperz.Crypto.BigInt(this.userData()['v'], 16); 356 v = new Clipperz.Crypto.BigInt(this.userData()['v'], 16);
345 this.set_B(v.add(Clipperz.Crypto.SRP.g().powerModule(this.b(), Clipperz.Crypto.SRP.n()))); 357 this.set_B((Clipperz.Crypto.SRP.k().multiply(v)).add(Clipperz.Crypto.SRP.g().powerModule(this.b(), Clipperz.Crypto.SRP.n())));
346 358
347 this.set_A(someParameters.parameters.A); 359 this.set_A(someParameters.parameters.A);
348 360
349 result['s'] = this.userData()['s']; 361 result['s'] = this.userData()['s'];
350 result['B'] = this.B().asString(16); 362 result['B'] = this.B().asString(16);
351 363
352 nextTollRequestType = 'CONNECT'; 364 nextTollRequestType = 'CONNECT';
353 } else if (someParameters.message == "credentialCheck") { 365 } else if (someParameters.message == "credentialCheck") {
354 var v, u, S, A, K, M1; 366 var v, u, s, S, A, K, M1;
367 var stringHash = function (aValue) {
368 return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2);
369 };
355 370
356//console.log(">>> Proxy.Offline.DataStore._handshake.credentialCheck", someParameters); 371//console.log(">>> Proxy.Offline.DataStore._handshake.credentialCheck", someParameters);
357 v = new Clipperz.Crypto.BigInt(this.userData()['v'], 16); 372 v = new Clipperz.Crypto.BigInt(this.userData()['v'], 16);
358 u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(this.B().asString(10))).toHexString(), 16);
359 A = new Clipperz.Crypto.BigInt(this.A(), 16); 373 A = new Clipperz.Crypto.BigInt(this.A(), 16);
374 u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + this.B().asString(10))).toHexString(), 16);
375 s = new Clipperz.Crypto.BigInt(this.userData()['s'], 16);
360 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(this.b(), Clipperz.Crypto.SRP.n()); 376 S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(this.b(), Clipperz.Crypto.SRP.n());
361 377
362 K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2); 378 K = stringHash(S.asString(10));
363 379
364 M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + this.B().asString(10) + K)).toHexString().slice(2); 380 M1 = stringHash(
381 "597626870978286801440197562148588907434001483655788865609375806439877501869636875571920406529" +
382 stringHash(this.C()) +
383 s.asString(10) +
384 A.asString(10) +
385 this.B().asString(10) +
386 K
387 );
365 if (someParameters.parameters.M1 == M1) { 388 if (someParameters.parameters.M1 == M1) {
366 var M2; 389 var M2;
367 390
368 M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2); 391 M2 = stringHash(
392 A.asString(10) +
393 someParameters.parameters.M1 +
394 K
395 );
369 result['M2'] = M2; 396 result['M2'] = M2;
370 } else { 397 } else {
371 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error"); 398 throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error");
372 } 399 }
373 400
374 nextTollRequestType = 'MESSAGE'; 401 nextTollRequestType = 'MESSAGE';
375 } else if (someParameters.message == "oneTimePassword") { 402 } else if (someParameters.message == "oneTimePassword") {
376 var otpData; 403 var otpData;
377 404
378//console.log("HANDSHAKE WITH OTP", someParameters.parameters.oneTimePasswordKey); 405//console.log("HANDSHAKE WITH OTP", someParameters.parameters.oneTimePasswordKey);
379//console.log("someParameters", someParameters); 406//console.log("someParameters", someParameters);
380//console.log("data.OTP", Clipperz.Base.serializeJSON(this.data()['onetimePasswords'])); 407//console.log("data.OTP", Clipperz.Base.serializeJSON(this.data()['onetimePasswords']));
381 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey]; 408 otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey];
382 409
383 try { 410 try {
384 if (typeof(otpData) != 'undefined') { 411 if (typeof(otpData) != 'undefined') {
385 if (otpData['status'] == 'ACTIVE') { 412 if (otpData['status'] == 'ACTIVE') {
386 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) { 413 if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) {
387 result = { 414 result = {
388 'data': otpData['data'], 415 'data': otpData['data'],
389 'version':otpData['version'] 416 'version':otpData['version']
390 } 417 }
391 418
392 otpData['status'] = 'REQUESTED'; 419 otpData['status'] = 'REQUESTED';
393 } else { 420 } else {
394 otpData['status'] = 'DISABLED'; 421 otpData['status'] = 'DISABLED';
395 throw "The requested One Time Password has been disabled, due to a wrong keyChecksum"; 422 throw "The requested One Time Password has been disabled, due to a wrong keyChecksum";
396 } 423 }
397 } else { 424 } else {
398 throw "The requested One Time Password was not active"; 425 throw "The requested One Time Password was not active";
399 } 426 }
400 } else { 427 } else {
401 throw "The requested One Time Password has not been found" 428 throw "The requested One Time Password has not been found"
402 } 429 }
403 } catch (exception) { 430 } catch (exception) {
404 result = { 431 result = {
405 'data': Clipperz.PM.Crypto.randomKey(), 432 'data': Clipperz.PM.Crypto.randomKey(),
406 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion 433 'version':Clipperz.PM.Connection.communicationProtocol.currentVersion
407 } 434 }
408 } 435 }
409 nextTollRequestType = 'CONNECT'; 436 nextTollRequestType = 'CONNECT';
410 } else { 437 } else {
411 MochiKit.Logging.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message); 438 MochiKit.Logging.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message);
412 } 439 }
413//console.log("<<< Proxy.Offline._handshake", result); 440//console.log("<<< Proxy.Offline._handshake", result);
414 441
415 result = { 442 result = {
416 result: result, 443 result: result,
417 toll: this.getTollForRequestType(nextTollRequestType) 444 toll: this.getTollForRequestType(nextTollRequestType)
418 } 445 }
419 446
420 return MochiKit.Async.succeed(result); 447 return MochiKit.Async.succeed(result);
421 }, 448 },
422 449
423 //------------------------------------------------------------------------- 450 //-------------------------------------------------------------------------
424 451
425 '_message': function(someParameters) { 452 '_message': function(someParameters) {
426 var result; 453 var result;
427 454
428 result = {}; 455 result = {};
429 456
430 //===================================================================== 457 //=====================================================================
431 // 458 //
432 // R E A D - O N L Y M e t h o d s 459 // R E A D - O N L Y M e t h o d s
433 // 460 //
434 //===================================================================== 461 //=====================================================================
435 if (someParameters.message == 'getUserDetails') { 462 if (someParameters.message == 'getUserDetails') {
436 var recordsStats; 463 var recordsStats;
437 var recordReference; 464 var recordReference;
438 465
439 //try { 466 //try {
440 recordsStats = {}; 467 recordsStats = {};
441 for (recordReference in this.userData()['records']) { 468 for (recordReference in this.userData()['records']) {
442 recordsStats[recordReference] = { 469 recordsStats[recordReference] = {
443 'updateDate': this.userData()['records'][recordReference]['updateDate'] 470 'updateDate': this.userData()['records'][recordReference]['updateDate']
444 } 471 }
445 } 472 }
446 473
447 result['header'] = this.userDetails(); 474 result['header'] = this.userDetails();
448 result['statistics'] = this.statistics(); 475 result['statistics'] = this.statistics();
449 result['maxNumberOfRecords'] = this.userData()['maxNumberOfRecords']; 476 result['maxNumberOfRecords'] = this.userData()['maxNumberOfRecords'];
450 result['version'] = this.userData()['userDetailsVersion']; 477 result['version'] = this.userData()['userDetailsVersion'];
451 result['recordsStats'] = recordsStats; 478 result['recordsStats'] = recordsStats;
452 479
453 if (this.isReadOnly() == false) { 480 if (this.isReadOnly() == false) {
454 varlock; 481 varlock;
455 482
456 if (typeof(this.userData()['lock']) == 'undefined') { 483 if (typeof(this.userData()['lock']) == 'undefined') {
457 this.userData()['lock'] = "<<LOCK>>"; 484 this.userData()['lock'] = "<<LOCK>>";
458 } 485 }
459 486
460 result['lock'] = this.userData()['lock']; 487 result['lock'] = this.userData()['lock'];
461 } 488 }
462//} catch (exception) { 489//} catch (exception) {
463 //console.log("*#*#*#*#*#*#*", exception); 490 //console.log("*#*#*#*#*#*#*", exception);
464 //throw exception; 491 //throw exception;
465//} 492//}
466 //===================================================================== 493 //=====================================================================
467 } else if (someParameters.message == 'getRecordDetail') { 494 } else if (someParameters.message == 'getRecordDetail') {
468 recordData = this.userData()['records'][someParameters['parameters']['reference']]; 495 recordData = this.userData()['records'][someParameters['parameters']['reference']];
469 496
470 result['reference'] = someParameters['parameters']['reference']; 497 result['reference'] = someParameters['parameters']['reference'];
471 result['data'] = recordData['data']; 498 result['data'] = recordData['data'];
472 result['version'] = recordData['version']; 499 result['version'] = recordData['version'];
473 result['creationData'] = recordData['creationDate']; 500 result['creationData'] = recordData['creationDate'];
474 result['updateDate'] = recordData['updateDate']; 501 result['updateDate'] = recordData['updateDate'];
475 result['accessDate'] = recordData['accessDate']; 502 result['accessDate'] = recordData['accessDate'];
476 503
477 currentVersionData = recordData['versions'][recordData['currentVersion']]; 504 currentVersionData = recordData['versions'][recordData['currentVersion']];
478 505
479 result['currentVersion'] = {}; 506 result['currentVersion'] = {};
480 result['currentVersion']['reference'] = recordData['currentVersion']; 507 result['currentVersion']['reference'] = recordData['currentVersion'];
481 result['currentVersion']['version'] = currentVersionData['version']; 508 result['currentVersion']['version'] = currentVersionData['version'];
482 result['currentVersion']['header'] = currentVersionData['header']; 509 result['currentVersion']['header'] = currentVersionData['header'];
483 result['currentVersion']['data'] = currentVersionData['data']; 510 result['currentVersion']['data'] = currentVersionData['data'];
484 result['currentVersion']['creationData'] = currentVersionData['creationDate']; 511 result['currentVersion']['creationData'] = currentVersionData['creationDate'];
485 result['currentVersion']['updateDate'] = currentVersionData['updateDate']; 512 result['currentVersion']['updateDate'] = currentVersionData['updateDate'];
486 result['currentVersion']['accessDate'] = currentVersionData['accessDate']; 513 result['currentVersion']['accessDate'] = currentVersionData['accessDate'];
487 if (typeof(currentVersionData['previousVersion']) != 'undefined') { 514 if (typeof(currentVersionData['previousVersion']) != 'undefined') {
488 result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey']; 515 result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey'];
489 result['currentVersion']['previousVersion'] = currentVersionData['previousVersion']; 516 result['currentVersion']['previousVersion'] = currentVersionData['previousVersion'];
490 } 517 }
491 518
492 //===================================================================== 519 //=====================================================================
493 // 520 //
494 // R E A D - W R I T E M e t h o d s 521 // R E A D - W R I T E M e t h o d s
495 // 522 //
496 //===================================================================== 523 //=====================================================================
497 } else if (someParameters.message == 'upgradeUserCredentials') { 524 } else if (someParameters.message == 'upgradeUserCredentials') {
498 if (this.isReadOnly() == false) { 525 if (this.isReadOnly() == false) {
499 var parameters; 526 var parameters;
500 parameters = someParameters.parameters; 527 parameters = someParameters.parameters;
501 528
502 if (parameters['C'] == null) { 529 if (parameters['C'] == null) {
503 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; 530 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed;
504 } else if (parameters['s'] == null) { 531 } else if (parameters['s'] == null) {
505 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; 532 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed;
506 } else if (parameters['v'] == null) { 533 } else if (parameters['v'] == null) {
507 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; 534 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed;
508 } else if (parameters['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion) { 535 } else if (parameters['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion) {
509 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed; 536 result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed;
510 } else { 537 } else {
511 result = {result:"done", parameters:parameters}; 538 result = {result:"done", parameters:parameters};
512 } 539 }
513 } else { 540 } else {
514 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 541 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
515 } 542 }
516 //===================================================================== 543 //=====================================================================
517 /* } else if (someParameters.message == 'updateData') { 544 /* } else if (someParameters.message == 'updateData') {
518 if (this.isReadOnly() == false) { 545 if (this.isReadOnly() == false) {
519 var i, c; 546 var i, c;
520 547
521//console.log("###==============================================================="); 548//console.log("###===============================================================");
522//console.log("###>>>", Clipperz.Base.serializeJSON(someParameters)); 549//console.log("###>>>", Clipperz.Base.serializeJSON(someParameters));
523//console.log("###--- userData", Clipperz.Base.serializeJSON(this.userData())); 550//console.log("###--- userData", Clipperz.Base.serializeJSON(this.userData()));
524 if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) { 551 if (this.userData()['lock']!= someParameters['parameters']['user']['lock']) {
525 throw "the lock attribute is not processed correctly" 552 throw "the lock attribute is not processed correctly"
526 } 553 }
527 554
528 this.userData()['userDetails'] = someParameters['parameters']['user']['header']; 555 this.userData()['userDetails'] = someParameters['parameters']['user']['header'];
529 this.userData()['statistics'] = someParameters['parameters']['user']['statistics']; 556 this.userData()['statistics'] = someParameters['parameters']['user']['statistics'];
530 this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version']; 557 this.userData()['userDetailsVersions']= someParameters['parameters']['user']['version'];
531 558
532 c = someParameters['parameters']['records'].length; 559 c = someParameters['parameters']['records'].length;
533 for (i=0; i<c; i++) { 560 for (i=0; i<c; i++) {
534 var currentRecord; 561 var currentRecord;
535 var currentRecordData; 562 var currentRecordData;
536 563
537 currentRecordData = someParameters['parameters']['records'][i]; 564 currentRecordData = someParameters['parameters']['records'][i];
538 currentRecord = this.userData()['records'][currentRecordData['record']['reference']]; 565 currentRecord = this.userData()['records'][currentRecordData['record']['reference']];
539 566
540 if (currentRecord == null) { 567 if (currentRecord == null) {
541 } 568 }
542 569
543 currentRecord['data'] = currentRecordData['record']['data']; 570 currentRecord['data'] = currentRecordData['record']['data'];
544 currentRecord['version'] = currentRecordData['record']['version']; 571 currentRecord['version'] = currentRecordData['record']['version'];
545 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference']; 572 currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference'];
546 573
547 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = { 574 currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = {
548 'data': currentRecordData['currentRecordVersion']['data'], 575 'data': currentRecordData['currentRecordVersion']['data'],
549 'version': currentRecordData['currentRecordVersion']['version'], 576 'version': currentRecordData['currentRecordVersion']['version'],
550 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'], 577 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'],
551 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey'] 578 'previousVersionKey':currentRecordData['currentRecordVersion']['previousVersionKey']
552 } 579 }
553 } 580 }
554 581
555 this.userData()['lock'] = Clipperz.PM.Crypto.randomKey(); 582 this.userData()['lock'] = Clipperz.PM.Crypto.randomKey();
556 result['lock'] = this.userData()['lock']; 583 result['lock'] = this.userData()['lock'];
557 result['result'] = 'done'; 584 result['result'] = 'done';
558//console.log("###<<< userData", Clipperz.Base.serializeJSON(this.userData())); 585//console.log("###<<< userData", Clipperz.Base.serializeJSON(this.userData()));
559 } else { 586 } else {
560 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly; 587 throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;