summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/Clipperz/PM/Connection.js
Unidiff
Diffstat (limited to 'frontend/gamma/js/Clipperz/PM/Connection.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/gamma/js/Clipperz/PM/Connection.js34
1 files changed, 29 insertions, 5 deletions
diff --git a/frontend/gamma/js/Clipperz/PM/Connection.js b/frontend/gamma/js/Clipperz/PM/Connection.js
index b4e8aaa..a05a310 100644
--- a/frontend/gamma/js/Clipperz/PM/Connection.js
+++ b/frontend/gamma/js/Clipperz/PM/Connection.js
@@ -20,48 +20,49 @@ refer to http://www.clipperz.com.
20* You should have received a copy of the GNU Affero General Public 20* You should have received a copy of the GNU Affero General Public
21 License along with Clipperz Community Edition. If not, see 21 License along with Clipperz Community Edition. If not, see
22 <http://www.gnu.org/licenses/>. 22 <http://www.gnu.org/licenses/>.
23 23
24*/ 24*/
25 25
26if (typeof(Clipperz) == 'undefined') { Clipperz = {}; } 26if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
27if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; } 27if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
28 28
29//----------------------------------------------------------------------------- 29//-----------------------------------------------------------------------------
30// 30//
31 // Abstract C O N N E C T I O N class 31 // Abstract C O N N E C T I O N class
32// 32//
33//----------------------------------------------------------------------------- 33//-----------------------------------------------------------------------------
34 34
35Clipperz.PM.Connection = function (args) { 35Clipperz.PM.Connection = function (args) {
36 args = args || {}; 36 args = args || {};
37 37
38 this._proxy = args.proxy || Clipperz.PM.Proxy.defaultProxy; 38 this._proxy = args.proxy || Clipperz.PM.Proxy.defaultProxy;
39 this._getCredentialsFunction = args.getCredentialsFunction; 39 this._getCredentialsFunction = args.getCredentialsFunction;
40 40
41 this._clipperz_pm_crypto_version = null; 41 this._clipperz_pm_crypto_version = null;
42 this._connectionId = null; 42 this._connectionId = null;
43 this._sharedSecret = null; 43 this._sharedSecret = null;
44 this._serverLockValue = null;
44 45
45 return this; 46 return this;
46} 47}
47 48
48Clipperz.PM.Connection.prototype = MochiKit.Base.update(null, { 49Clipperz.PM.Connection.prototype = MochiKit.Base.update(null, {
49 50
50 'toString': function() { 51 'toString': function() {
51 return "Connection [" + this.version() + "]"; 52 return "Connection [" + this.version() + "]";
52 }, 53 },
53 54
54 //========================================================================= 55 //=========================================================================
55 56
56 'version': function() { 57 'version': function() {
57 throw Clipperz.Base.exception.AbstractMethod; 58 throw Clipperz.Base.exception.AbstractMethod;
58 }, 59 },
59 60
60 'clipperz_pm_crypto_version': function() { 61 'clipperz_pm_crypto_version': function() {
61 if (this._clipperz_pm_crypto_version == null) { 62 if (this._clipperz_pm_crypto_version == null) {
62 var connectionVersions; 63 var connectionVersions;
63 varversions; 64 varversions;
64 varversion; 65 varversion;
65 var i, c; 66 var i, c;
66 67
67 version = null; 68 version = null;
@@ -125,48 +126,58 @@ MochiKit.Logging.logError("### Connection.defaultErrorHandler: " + anErrorString
125 'serverSideUserCredentials': function() { 126 'serverSideUserCredentials': function() {
126 throw Clipperz.Base.exception.AbstractMethod; 127 throw Clipperz.Base.exception.AbstractMethod;
127 }, 128 },
128 129
129 //========================================================================= 130 //=========================================================================
130 131
131 'sharedSecret': function () { 132 'sharedSecret': function () {
132 return this._sharedSecret; 133 return this._sharedSecret;
133 }, 134 },
134 135
135 'setSharedSecret': function (aValue) { 136 'setSharedSecret': function (aValue) {
136 this._sharedSecret = aValue; 137 this._sharedSecret = aValue;
137 }, 138 },
138 139
139 //------------------------------------------------------------------------- 140 //-------------------------------------------------------------------------
140 141
141 'connectionId': function() { 142 'connectionId': function() {
142 return this._connectionId; 143 return this._connectionId;
143 }, 144 },
144 145
145 'setConnectionId': function(aValue) { 146 'setConnectionId': function(aValue) {
146 this._connectionId = aValue; 147 this._connectionId = aValue;
147 }, 148 },
148 149
150 //-------------------------------------------------------------------------
151
152 'serverLockValue': function () {
153 return this._serverLockValue;
154 },
155
156 'setServerLockValue': function (aValue) {
157 this._serverLockValue = aValue;
158 },
159
149 //========================================================================= 160 //=========================================================================
150/* 161/*
151 //TODO: ????? 162 //TODO: ?????
152 'oneTimePassword': function() { 163 'oneTimePassword': function() {
153 return this._oneTimePassword; 164 return this._oneTimePassword;
154 }, 165 },
155 166
156 'setOneTimePassword': function(aValue) { 167 'setOneTimePassword': function(aValue) {
157 this._oneTimePassword = aValue; 168 this._oneTimePassword = aValue;
158 }, 169 },
159*/ 170*/
160 //========================================================================= 171 //=========================================================================
161 172
162 'reset': function() { 173 'reset': function() {
163 this.setSharedSecret(null); 174 this.setSharedSecret(null);
164 this.setConnectionId(null); 175 this.setConnectionId(null);
165 }, 176 },
166 177
167 //========================================================================= 178 //=========================================================================
168 __syntaxFix__: "syntax fix" 179 __syntaxFix__: "syntax fix"
169 180
170} 181}
171); 182);
172 183
@@ -299,55 +310,54 @@ Clipperz.PM.Connection.SRP['1.0'].prototype = MochiKit.Base.update(new Clipperz.
299 args = { 310 args = {
300 'message': 'oneTimePassword', 311 'message': 'oneTimePassword',
301 'version': Clipperz.PM.Connection.communicationProtocol.currentVersion, 312 'version': Clipperz.PM.Connection.communicationProtocol.currentVersion,
302 'parameters': { 313 'parameters': {
303 'oneTimePasswordKey': Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(someParameters['username'], normalizedOTP), 314 'oneTimePasswordKey': Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(someParameters['username'], normalizedOTP),
304 'oneTimePasswordKeyChecksum':Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(someParameters['username'], normalizedOTP) 315 'oneTimePasswordKeyChecksum':Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(someParameters['username'], normalizedOTP)
305 } 316 }
306 } 317 }
307 318
308 return Clipperz.Async.callbacks("Connction.redeemOTP", [ 319 return Clipperz.Async.callbacks("Connction.redeemOTP", [
309 MochiKit.Base.method(this.proxy(), 'handshake', args), 320 MochiKit.Base.method(this.proxy(), 'handshake', args),
310 function(aResult) { 321 function(aResult) {
311 return Clipperz.PM.Crypto.deferredDecrypt({ 322 return Clipperz.PM.Crypto.deferredDecrypt({
312 value:aResult['data'], 323 value:aResult['data'],
313 key:normalizedOTP, 324 key:normalizedOTP,
314 version:aResult['version'] 325 version:aResult['version']
315 }); 326 });
316 }, 327 },
317 function(aResult) { 328 function(aResult) {
318 return (new Clipperz.ByteArray().appendBase64String(aResult['passphrase'])).asString(); 329 return (new Clipperz.ByteArray().appendBase64String(aResult['passphrase'])).asString();
319 } 330 }
320 ], {trace:false}) 331 ], {trace:false})
321 }, 332 },
322 333
323 'login': function(/*anUsername, aPassphrase*/) { 334 'login': function(isReconnecting) {
324 vardeferredResult; 335 vardeferredResult;
325 var cryptoVersion; 336 var cryptoVersion;
326 var srpConnection; 337 var srpConnection;
327 338
328 cryptoVersion = this.clipperz_pm_crypto_version(); 339 cryptoVersion = this.clipperz_pm_crypto_version();
329
330 deferredResult = new Clipperz.Async.Deferred("Connection.login", {trace:false}); 340 deferredResult = new Clipperz.Async.Deferred("Connection.login", {trace:false});
331 deferredResult.addCallback(this.getCredentialsFunction()); 341 deferredResult.addCallback(this.getCredentialsFunction());
332 deferredResult.addMethod(this, 'normalizedCredentials'); 342 deferredResult.addMethod(this, 'normalizedCredentials');
333 // deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_sendingCredentials'); 343 // deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_sendingCredentials');
334 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); 344 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
335 deferredResult.addCallback(MochiKit.Base.bind(function(someCredentials) { 345 deferredResult.addCallback(MochiKit.Base.bind(function(someCredentials) {
336 srpConnection = new Clipperz.Crypto.SRP.Connection({ C:someCredentials['username'], P:someCredentials['password'], hash:this.hash() }); 346 srpConnection = new Clipperz.Crypto.SRP.Connection({ C:someCredentials['username'], P:someCredentials['password'], hash:this.hash() });
337 }, this)); 347 }, this));
338 deferredResult.addCallback(function() { 348 deferredResult.addCallback(function() {
339 var result; 349 var result;
340 350
341 result = { 351 result = {
342 message: 'connect', 352 message: 'connect',
343 version: cryptoVersion, 353 version: cryptoVersion,
344 parameters: { 354 parameters: {
345 C: srpConnection.C(), 355 C: srpConnection.C(),
346 A: srpConnection.A().asString(16) 356 A: srpConnection.A().asString(16)
347 // reconnecting: this.connectionId() 357 // reconnecting: this.connectionId()
348 } 358 }
349 }; 359 };
350 360
351 // TODO: ????? 361 // TODO: ?????
352 // if (isReconnecting == true) { 362 // if (isReconnecting == true) {
353 // args.parameters['reconnecting'] = aConnection.connectionId(); 363 // args.parameters['reconnecting'] = aConnection.connectionId();
@@ -378,100 +388,113 @@ Clipperz.PM.Connection.SRP['1.0'].prototype = MochiKit.Base.update(new Clipperz.
378 }; 388 };
379 389
380 return result; 390 return result;
381 }); 391 });
382 deferredResult.addMethod(this.proxy(), 'handshake'); 392 deferredResult.addMethod(this.proxy(), 'handshake');
383 deferredResult.addCallback(function(someParameters) { 393 deferredResult.addCallback(function(someParameters) {
384 var result; 394 var result;
385 395
386 if (someParameters['M2'] == srpConnection.M2()) { 396 if (someParameters['M2'] == srpConnection.M2()) {
387 result = MochiKit.Async.succeed(someParameters); 397 result = MochiKit.Async.succeed(someParameters);
388 } else { 398 } else {
389 result = MochiKit.Async.fail(Clipperz.PM.Connection.exception.WrongChecksum); 399 result = MochiKit.Async.fail(Clipperz.PM.Connection.exception.WrongChecksum);
390 } 400 }
391 401
392 return result; 402 return result;
393 }); 403 });
394 deferredResult.addCallback(MochiKit.Base.bind(function(someParameters) { 404 deferredResult.addCallback(MochiKit.Base.bind(function(someParameters) {
395 this.setConnectionId(someParameters['connectionId']); 405 this.setConnectionId(someParameters['connectionId']);
396 this.setSharedSecret(srpConnection.K()); 406 this.setSharedSecret(srpConnection.K());
397 407
398 // TODO: ????? 408 // TODO: ?????
399 // if (this.oneTimePassword() != null) { 409 // if (this.oneTimePassword() != null) {
400 /// ?? result = this.user().oneTimePasswordManager().archiveOneTimePassword(this.oneTimePassword())); 410 /// ?? result = this.user().oneTimePasswordManager().archiveOneTimePassword(this.oneTimePassword()));
401 // } 411 // }
412
413 if ((isReconnecting == true) && (this.serverLockValue() != someParameters['lock'])) {
414 throw Clipperz.PM.Connection.exception.StaleData;
415 } else {
416 this.setServerLockValue(someParameters['lock']);
417 }
418
402 return someParameters; 419 return someParameters;
403 }, this)); 420 }, this));
404 // deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_loggedIn'); 421 // deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_loggedIn');
405 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress'); 422 deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
406 deferredResult.addCallback(MochiKit.Async.succeed, {result:"done"}); 423 deferredResult.addCallback(MochiKit.Async.succeed, {result:"done"});
407 424
408 deferredResult.callback(); 425 deferredResult.callback();
409 426
410 return deferredResult; 427 return deferredResult;
411 }, 428 },
412 429
413 //========================================================================= 430 //=========================================================================
414 431
415 'logout': function() { 432 'logout': function() {
416 return Clipperz.Async.callbacks("Connection.logout", [ 433 return Clipperz.Async.callbacks("Connection.logout", [
417 MochiKit.Base.method(this, 'setSharedSecret'), 434 MochiKit.Base.method(this, 'setSharedSecret'),
418 MochiKit.Base.method(this.proxy(), 'logout', {}) 435 MochiKit.Base.method(this.proxy(), 'logout', {})
419 ], {trace:false}); 436 ], {trace:false});
420 }, 437 },
421 438
422 //========================================================================= 439 //=========================================================================
423 440
424 'ping': function () { 441 'ping': function () {
425 //TODO: ping the server in order to have a valid session 442 //TODO: ping the server in order to have a valid session
426 }, 443 },
427 444
428 //========================================================================= 445 //=========================================================================
429 446
430 'message': function(aMessageName, someParameters) { 447 'message': function(aMessageName, someParameters) {
431 var args; 448 var args;
449 var parameters;
450
451 parameters = someParameters || {};
452 if (typeof(parameters['user']) != 'undefined') {
453 parameters['user']['lock'] = this.serverLockValue();
454 }
432 455
433//console.log(">>> Connection.message", aMessageName, someParameters); 456//console.log(">>> Connection.message", aMessageName, someParameters);
434 args = { 457 args = {
435 message: aMessageName, 458 message: aMessageName,
436 srpSharedSecret: this.sharedSecret(), 459 srpSharedSecret: this.sharedSecret(),
437 parameters: (someParameters || {}) 460 // parameters: (someParameters || {})
461 parameters: parameters
438 } 462 }
439 463
440 return this.sendMessage(args); 464 return this.sendMessage(args);
441 }, 465 },
442 466
443 //------------------------------------------------------------------------- 467 //-------------------------------------------------------------------------
444 468
445 'sendMessage': function(someArguments) { 469 'sendMessage': function(someArguments) {
446 vardeferredResult; 470 vardeferredResult;
447 471
448 deferredResult = new Clipperz.Async.Deferred("Connection.sendMessage", {trace:false}); 472 deferredResult = new Clipperz.Async.Deferred("Connection.sendMessage", {trace:false});
449 deferredResult.addMethod(this.proxy(), 'message', someArguments); 473 deferredResult.addMethod(this.proxy(), 'message', someArguments);
450 deferredResult.addCallback(MochiKit.Base.bind(function(res) { 474 deferredResult.addCallback(MochiKit.Base.bind(function(res) {
451 if (typeof(res['lock']) != 'undefined') { 475 if (typeof(res['lock']) != 'undefined') {
452 //TODO: ????? 476 this.setServerLockValue(res['lock']);
453 // ?? this.user().setLock(res['lock']);
454 } 477 }
455 return res; 478 return res;
456 }, this)); 479 }, this));
457 480
458 deferredResult.addErrback(MochiKit.Base.method(this, 'messageExceptionHandler'), someArguments); 481 deferredResult.addErrback(MochiKit.Base.method(this, 'messageExceptionHandler'), someArguments);
459 deferredResult.callback(); 482 deferredResult.callback();
460 483
461 return deferredResult 484 return deferredResult
462 }, 485 },
463 486
464 //------------------------------------------------------------------------- 487 //-------------------------------------------------------------------------
465 488
466 'messageExceptionHandler': function(anOriginalMessageArguments, anError) { 489 'messageExceptionHandler': function(anOriginalMessageArguments, anError) {
467 var result; 490 var result;
468 491
469console.log(">>> Connection.messageExceptionHandler", anError, anError.message); 492console.log(">>> Connection.messageExceptionHandler", anError, anError.message);
470 if (anError instanceof MochiKit.Async.CancelledError) { 493 if (anError instanceof MochiKit.Async.CancelledError) {
471 result = anError; 494 result = anError;
472 } else { 495 } else {
473 if ((anError.message == 'Trying to communicate without an active connection')|| 496 if ((anError.message == 'Trying to communicate without an active connection')||
474 (anError.message == 'No tollManager available for current session') 497 (anError.message == 'No tollManager available for current session')
475 ) { 498 ) {
476 result = this.reestablishConnection(anOriginalMessageArguments); 499 result = this.reestablishConnection(anOriginalMessageArguments);
477 } else if (anError.message == 'Session with stale data') { 500 } else if (anError.message == 'Session with stale data') {
@@ -566,48 +589,49 @@ Clipperz.PM.Connection.SRP['1.1'].prototype = MochiKit.Base.update(new Clipperz.
566 589
567 'normalizedCredentials': function(someValues) { 590 'normalizedCredentials': function(someValues) {
568 var result; 591 var result;
569 592
570 result = {} 593 result = {}
571 result['username'] = this.hash()(new Clipperz.ByteArray(someValues['username'] + someValues['password'])).toHexString().substring(2); 594 result['username'] = this.hash()(new Clipperz.ByteArray(someValues['username'] + someValues['password'])).toHexString().substring(2);
572 result['password'] = this.hash()(new Clipperz.ByteArray(someValues['password'] + someValues['username'])).toHexString().substring(2); 595 result['password'] = this.hash()(new Clipperz.ByteArray(someValues['password'] + someValues['username'])).toHexString().substring(2);
573 596
574 return result; 597 return result;
575 }, 598 },
576 599
577 //----------------------------------------------------------------------------- 600 //-----------------------------------------------------------------------------
578 601
579 'hash': function() { 602 'hash': function() {
580 return Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].hash; 603 return Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].hash;
581 }, 604 },
582 605
583 //----------------------------------------------------------------------------- 606 //-----------------------------------------------------------------------------
584 __syntaxFix__: "syntax fix" 607 __syntaxFix__: "syntax fix"
585 608
586}); 609});
587 610
588Clipperz.PM.Connection.exception = { 611Clipperz.PM.Connection.exception = {
589 WrongChecksum: new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.InvalidValue"), 612 WrongChecksum: new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.InvalidValue"),
613 StaleData: new MochiKit.Base.NamedError("Stale data"),
590 UnexpectedRequest:new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.UnexpectedRequest") 614 UnexpectedRequest:new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.UnexpectedRequest")
591}; 615};
592 616
593 617
594Clipperz.PM.Connection.communicationProtocol = { 618Clipperz.PM.Connection.communicationProtocol = {
595 'currentVersion': '0.2', 619 'currentVersion': '0.2',
596 'versions': { 620 'versions': {
597 '0.1': Clipperz.PM.Connection.SRP['1.0'],//Clipperz.Crypto.SRP.versions['1.0'].Connection, 621 '0.1': Clipperz.PM.Connection.SRP['1.0'],//Clipperz.Crypto.SRP.versions['1.0'].Connection,
598 '0.2': Clipperz.PM.Connection.SRP['1.1']//Clipperz.Crypto.SRP.versions['1.1'].Connection 622 '0.2': Clipperz.PM.Connection.SRP['1.1']//Clipperz.Crypto.SRP.versions['1.1'].Connection
599 }, 623 },
600 'fallbackVersions': { 624 'fallbackVersions': {
601 // 'current':'0.1', 625 // 'current':'0.1',
602 '0.2': '0.1', 626 '0.2': '0.1',
603 '0.1': null 627 '0.1': null
604 } 628 }
605}; 629};
606 630
607MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.versions, { 631MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.versions, {
608 'current': Clipperz.PM.Connection.communicationProtocol.versions[Clipperz.PM.Connection.communicationProtocol.currentVersion] 632 'current': Clipperz.PM.Connection.communicationProtocol.versions[Clipperz.PM.Connection.communicationProtocol.currentVersion]
609}); 633});
610 634
611MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.fallbackVersions, { 635MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.fallbackVersions, {
612 'current': Clipperz.PM.Connection.communicationProtocol.fallbackVersions[Clipperz.PM.Connection.communicationProtocol.currentVersion] 636 'current': Clipperz.PM.Connection.communicationProtocol.fallbackVersions[Clipperz.PM.Connection.communicationProtocol.currentVersion]
613}); 637});