sasl.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.xmpp.sasl"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.xmpp.sasl"] = true;
  8. dojo.provide("dojox.xmpp.sasl");
  9. dojo.require("dojox.xmpp.util");
  10. dojo.require("dojo.AdapterRegistry");
  11. dojo.require("dojox.encoding.digests.MD5");
  12. dojox.xmpp.sasl.saslNS = "urn:ietf:params:xml:ns:xmpp-sasl";
  13. dojo.declare("dojox.xmpp.sasl._Base", null, {
  14. mechanism: null,
  15. closeAuthTag: true,
  16. constructor: function(session){
  17. this.session = session;
  18. this.startAuth();
  19. },
  20. startAuth: function(){
  21. var auth = new dojox.string.Builder(dojox.xmpp.util.createElement("auth", {
  22. xmlns: dojox.xmpp.sasl.saslNS,
  23. mechanism: this.mechanism
  24. }, this.closeAuthTag));
  25. this.appendToAuth(auth);
  26. this.session.dispatchPacket(auth.toString());
  27. },
  28. appendToAuth: function(auth){},
  29. onChallenge: function(msg){
  30. if(!this.first_challenge){
  31. this.first_challenge = true;
  32. this.onFirstChallenge(msg);
  33. }else{
  34. this.onSecondChallenge(msg);
  35. }
  36. },
  37. onFirstChallenge: function(){},
  38. onSecondChallenge: function(){},
  39. onSuccess: function(){
  40. this.session.sendRestart();
  41. }
  42. });
  43. dojo.declare("dojox.xmpp.sasl.SunWebClientAuth", dojox.xmpp.sasl._Base, {
  44. mechanism: "SUN-COMMS-CLIENT-PROXY-AUTH"
  45. });
  46. dojo.declare("dojox.xmpp.sasl.Plain", dojox.xmpp.sasl._Base, {
  47. mechanism: "PLAIN",
  48. closeAuthTag: false,
  49. appendToAuth: function(auth){
  50. var id = this.session.jid;
  51. var index = this.session.jid.indexOf('@');
  52. if (index != -1){
  53. id = this.session.jid.substring(0, index);
  54. }
  55. var token = this.session.jid + '\u0000' + id + '\u0000' + this.session.password;
  56. token = dojox.xmpp.util.Base64.encode(token);
  57. auth.append(token);
  58. auth.append("</auth>");
  59. delete this.session.password;
  60. }
  61. });
  62. dojo.declare("dojox.xmpp.sasl.DigestMD5", dojox.xmpp.sasl._Base, {
  63. mechanism: "DIGEST-MD5",
  64. onFirstChallenge: function(msg){
  65. var dxed = dojox.encoding.digests;
  66. var dxedo = dojox.encoding.digests.outputTypes;
  67. var HEX = function(n){
  68. return dxed.MD5(n, dxedo.Hex);
  69. };
  70. var H = function(s){
  71. return dxed.MD5(s, dxedo.String);
  72. };
  73. var ch_str = dojox.xmpp.util.Base64.decode(msg.firstChild.nodeValue);
  74. var ch = {
  75. realm: "",
  76. nonce: "",
  77. qop: "auth",
  78. maxbuf: 65536
  79. };
  80. ch_str.replace(/([a-z]+)=([^,]+)/g, function(t,k,v){
  81. v = v.replace(/^"(.+)"$/, "$1");
  82. ch[k] = v;
  83. });
  84. var A2_append = '';
  85. switch(ch.qop){
  86. case 'auth-int':
  87. case 'auth-conf':
  88. A2_append = ':00000000000000000000000000000000';
  89. case 'auth':
  90. break;
  91. default:
  92. return false;
  93. }
  94. var cnonce = dxed.MD5(Math.random() * 1234567890, dxedo.Hex);
  95. var digest_uri = 'xmpp/' + this.session.domain;
  96. var username = this.session.jid;
  97. var index = this.session.jid.indexOf('@');
  98. if (index != -1){
  99. username = this.session.jid.substring(0, index);
  100. }
  101. username = dojox.xmpp.util.encodeJid(username);
  102. var A1 = new dojox.string.Builder();
  103. A1.append(H(username + ':' + ch.realm + ':' + this.session.password),
  104. ':', ch.nonce + ':' + cnonce);
  105. delete this.session.password;
  106. var A2_rspauth = ':' + digest_uri + A2_append;
  107. var A2 = 'AUTHENTICATE' + A2_rspauth;
  108. var response_value = new dojox.string.Builder();
  109. response_value.append(HEX(A1.toString()), ':', ch.nonce, ':00000001:', cnonce, ':',
  110. ch.qop, ':')
  111. var ret = new dojox.string.Builder();
  112. ret.append('username="', username, '",',
  113. 'realm="', ch.realm, '",',
  114. 'nonce=', ch.nonce, ',',
  115. 'cnonce="', cnonce, '",',
  116. 'nc="00000001",qop="', ch.qop, '",digest-uri="', digest_uri, '",',
  117. 'response="', HEX(response_value.toString() + HEX(A2)), '",charset="utf-8"');
  118. var response = new dojox.string.Builder(dojox.xmpp.util.createElement("response", {
  119. xmlns: dojox.xmpp.xmpp.SASL_NS
  120. }, false));
  121. response.append(dojox.xmpp.util.Base64.encode(ret.toString()));
  122. response.append('</response>');
  123. this.rspauth = HEX(response_value.toString() + HEX(A2_rspauth));
  124. this.session.dispatchPacket(response.toString());
  125. },
  126. onSecondChallenge: function(msg){
  127. var ch_str = dojox.xmpp.util.Base64.decode(msg.firstChild.nodeValue);
  128. if(this.rspauth == ch_str.substring(8)){
  129. var response = new dojox.string.Builder(dojox.xmpp.util.createElement("response", {
  130. xmlns: dojox.xmpp.xmpp.SASL_NS
  131. }, true));
  132. this.session.dispatchPacket(response.toString());
  133. }else{
  134. //FIXME
  135. }
  136. }
  137. });
  138. dojox.xmpp.sasl.registry = new dojo.AdapterRegistry();
  139. dojox.xmpp.sasl.registry.register(
  140. 'SUN-COMMS-CLIENT-PROXY-AUTH',
  141. function(mechanism){
  142. return mechanism == 'SUN-COMMS-CLIENT-PROXY-AUTH';
  143. },
  144. function(mechanism, session){
  145. return new dojox.xmpp.sasl.SunWebClientAuth(session);
  146. }
  147. );
  148. dojox.xmpp.sasl.registry.register(
  149. 'DIGEST-MD5',
  150. function(mechanism){
  151. return mechanism == 'DIGEST-MD5';
  152. },
  153. function(mechanism, session){
  154. return new dojox.xmpp.sasl.DigestMD5(session);
  155. }
  156. );
  157. dojox.xmpp.sasl.registry.register(
  158. 'PLAIN',
  159. function(mechanism){
  160. return mechanism == 'PLAIN';
  161. },
  162. function(mechanism, session){
  163. return new dojox.xmpp.sasl.Plain(session);
  164. }
  165. );
  166. }