mirror of https://github.com/jitsi/jitsi-meet
parent
f0a278cad5
commit
8c64d3192b
@ -0,0 +1,202 @@ |
||||
/* |
||||
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined |
||||
* in FIPS PUB 180-1 |
||||
* Version 2.1a Copyright Paul Johnston 2000 - 2002. |
||||
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet |
||||
* Distributed under the BSD License |
||||
* See http://pajhome.org.uk/crypt/md5 for details.
|
||||
*/ |
||||
|
||||
/* |
||||
* Configurable variables. You may need to tweak these to be compatible with |
||||
* the server-side, but the defaults work in most cases. |
||||
*/ |
||||
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ |
||||
var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ |
||||
var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ |
||||
|
||||
/* |
||||
* These are the functions you'll usually want to call |
||||
* They take string arguments and return either hex or base-64 encoded strings |
||||
*/ |
||||
function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));} |
||||
function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));} |
||||
function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));} |
||||
function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));} |
||||
function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));} |
||||
function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));} |
||||
|
||||
/* |
||||
* Perform a simple self-test to see if the VM is working |
||||
*/ |
||||
function sha1_vm_test() |
||||
{ |
||||
return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d"; |
||||
} |
||||
|
||||
/* |
||||
* Calculate the SHA-1 of an array of big-endian words, and a bit length |
||||
*/ |
||||
function core_sha1(x, len) |
||||
{ |
||||
/* append padding */ |
||||
x[len >> 5] |= 0x80 << (24 - len % 32); |
||||
x[((len + 64 >> 9) << 4) + 15] = len; |
||||
|
||||
var w = Array(80); |
||||
var a = 1732584193; |
||||
var b = -271733879; |
||||
var c = -1732584194; |
||||
var d = 271733878; |
||||
var e = -1009589776; |
||||
|
||||
for(var i = 0; i < x.length; i += 16) |
||||
{ |
||||
var olda = a; |
||||
var oldb = b; |
||||
var oldc = c; |
||||
var oldd = d; |
||||
var olde = e; |
||||
|
||||
for(var j = 0; j < 80; j++) |
||||
{ |
||||
if(j < 16) w[j] = x[i + j]; |
||||
else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); |
||||
var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), |
||||
safe_add(safe_add(e, w[j]), sha1_kt(j))); |
||||
e = d; |
||||
d = c; |
||||
c = rol(b, 30); |
||||
b = a; |
||||
a = t; |
||||
} |
||||
|
||||
a = safe_add(a, olda); |
||||
b = safe_add(b, oldb); |
||||
c = safe_add(c, oldc); |
||||
d = safe_add(d, oldd); |
||||
e = safe_add(e, olde); |
||||
} |
||||
return Array(a, b, c, d, e); |
||||
|
||||
} |
||||
|
||||
/* |
||||
* Perform the appropriate triplet combination function for the current |
||||
* iteration |
||||
*/ |
||||
function sha1_ft(t, b, c, d) |
||||
{ |
||||
if(t < 20) return (b & c) | ((~b) & d); |
||||
if(t < 40) return b ^ c ^ d; |
||||
if(t < 60) return (b & c) | (b & d) | (c & d); |
||||
return b ^ c ^ d; |
||||
} |
||||
|
||||
/* |
||||
* Determine the appropriate additive constant for the current iteration |
||||
*/ |
||||
function sha1_kt(t) |
||||
{ |
||||
return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : |
||||
(t < 60) ? -1894007588 : -899497514; |
||||
} |
||||
|
||||
/* |
||||
* Calculate the HMAC-SHA1 of a key and some data |
||||
*/ |
||||
function core_hmac_sha1(key, data) |
||||
{ |
||||
var bkey = str2binb(key); |
||||
if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz); |
||||
|
||||
var ipad = Array(16), opad = Array(16); |
||||
for(var i = 0; i < 16; i++) |
||||
{ |
||||
ipad[i] = bkey[i] ^ 0x36363636; |
||||
opad[i] = bkey[i] ^ 0x5C5C5C5C; |
||||
} |
||||
|
||||
var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz); |
||||
return core_sha1(opad.concat(hash), 512 + 160); |
||||
} |
||||
|
||||
/* |
||||
* Add integers, wrapping at 2^32. This uses 16-bit operations internally |
||||
* to work around bugs in some JS interpreters. |
||||
*/ |
||||
function safe_add(x, y) |
||||
{ |
||||
var lsw = (x & 0xFFFF) + (y & 0xFFFF); |
||||
var msw = (x >> 16) + (y >> 16) + (lsw >> 16); |
||||
return (msw << 16) | (lsw & 0xFFFF); |
||||
} |
||||
|
||||
/* |
||||
* Bitwise rotate a 32-bit number to the left. |
||||
*/ |
||||
function rol(num, cnt) |
||||
{ |
||||
return (num << cnt) | (num >>> (32 - cnt)); |
||||
} |
||||
|
||||
/* |
||||
* Convert an 8-bit or 16-bit string to an array of big-endian words |
||||
* In 8-bit function, characters >255 have their hi-byte silently ignored. |
||||
*/ |
||||
function str2binb(str) |
||||
{ |
||||
var bin = Array(); |
||||
var mask = (1 << chrsz) - 1; |
||||
for(var i = 0; i < str.length * chrsz; i += chrsz) |
||||
bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32); |
||||
return bin; |
||||
} |
||||
|
||||
/* |
||||
* Convert an array of big-endian words to a string |
||||
*/ |
||||
function binb2str(bin) |
||||
{ |
||||
var str = ""; |
||||
var mask = (1 << chrsz) - 1; |
||||
for(var i = 0; i < bin.length * 32; i += chrsz) |
||||
str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask); |
||||
return str; |
||||
} |
||||
|
||||
/* |
||||
* Convert an array of big-endian words to a hex string. |
||||
*/ |
||||
function binb2hex(binarray) |
||||
{ |
||||
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; |
||||
var str = ""; |
||||
for(var i = 0; i < binarray.length * 4; i++) |
||||
{ |
||||
str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + |
||||
hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF); |
||||
} |
||||
return str; |
||||
} |
||||
|
||||
/* |
||||
* Convert an array of big-endian words to a base-64 string |
||||
*/ |
||||
function binb2b64(binarray) |
||||
{ |
||||
var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
||||
var str = ""; |
||||
for(var i = 0; i < binarray.length * 4; i += 3) |
||||
{ |
||||
var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16) |
||||
| (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) |
||||
| ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF); |
||||
for(var j = 0; j < 4; j++) |
||||
{ |
||||
if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; |
||||
else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); |
||||
} |
||||
} |
||||
return str; |
||||
} |
@ -0,0 +1,232 @@ |
||||
/* |
||||
Copyright 2010, François de Metz <francois@2metz.fr> |
||||
*/ |
||||
|
||||
/** |
||||
* Disco Strophe Plugin |
||||
* Implement http://xmpp.org/extensions/xep-0030.html
|
||||
* TODO: manage node hierarchies, and node on info request |
||||
*/ |
||||
Strophe.addConnectionPlugin('disco', |
||||
{ |
||||
_connection: null, |
||||
_identities : [], |
||||
_features : [], |
||||
_items : [], |
||||
/** Function: init |
||||
* Plugin init |
||||
* |
||||
* Parameters: |
||||
* (Strophe.Connection) conn - Strophe connection |
||||
*/ |
||||
init: function(conn) |
||||
{ |
||||
this._connection = conn; |
||||
this._identities = []; |
||||
this._features = []; |
||||
this._items = []; |
||||
// disco info
|
||||
conn.addHandler(this._onDiscoInfo.bind(this), Strophe.NS.DISCO_INFO, 'iq', 'get', null, null); |
||||
// disco items
|
||||
conn.addHandler(this._onDiscoItems.bind(this), Strophe.NS.DISCO_ITEMS, 'iq', 'get', null, null); |
||||
}, |
||||
/** Function: addIdentity |
||||
* See http://xmpp.org/registrar/disco-categories.html
|
||||
* Parameters: |
||||
* (String) category - category of identity (like client, automation, etc ...) |
||||
* (String) type - type of identity (like pc, web, bot , etc ...) |
||||
* (String) name - name of identity in natural language |
||||
* (String) lang - lang of name parameter |
||||
* |
||||
* Returns: |
||||
* Boolean |
||||
*/ |
||||
addIdentity: function(category, type, name, lang) |
||||
{ |
||||
for (var i=0; i<this._identities.length; i++) |
||||
{ |
||||
if (this._identities[i].category == category && |
||||
this._identities[i].type == type && |
||||
this._identities[i].name == name && |
||||
this._identities[i].lang == lang) |
||||
{ |
||||
return false; |
||||
} |
||||
} |
||||
this._identities.push({category: category, type: type, name: name, lang: lang}); |
||||
return true; |
||||
}, |
||||
/** Function: addFeature |
||||
* |
||||
* Parameters: |
||||
* (String) var_name - feature name (like jabber:iq:version) |
||||
* |
||||
* Returns: |
||||
* boolean |
||||
*/ |
||||
addFeature: function(var_name) |
||||
{ |
||||
for (var i=0; i<this._features.length; i++) |
||||
{ |
||||
if (this._features[i] == var_name) |
||||
return false; |
||||
} |
||||
this._features.push(var_name); |
||||
return true; |
||||
}, |
||||
/** Function: removeFeature |
||||
* |
||||
* Parameters: |
||||
* (String) var_name - feature name (like jabber:iq:version) |
||||
* |
||||
* Returns: |
||||
* boolean |
||||
*/ |
||||
removeFeature: function(var_name) |
||||
{ |
||||
for (var i=0; i<this._features.length; i++) |
||||
{ |
||||
if (this._features[i] === var_name){ |
||||
this._features.splice(i,1) |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
}, |
||||
/** Function: addItem |
||||
* |
||||
* Parameters: |
||||
* (String) jid |
||||
* (String) name |
||||
* (String) node |
||||
* (Function) call_back |
||||
* |
||||
* Returns: |
||||
* boolean |
||||
*/ |
||||
addItem: function(jid, name, node, call_back) |
||||
{ |
||||
if (node && !call_back) |
||||
return false; |
||||
this._items.push({jid: jid, name: name, node: node, call_back: call_back}); |
||||
return true; |
||||
}, |
||||
/** Function: info |
||||
* Info query |
||||
* |
||||
* Parameters: |
||||
* (Function) call_back |
||||
* (String) jid |
||||
* (String) node |
||||
*/ |
||||
info: function(jid, node, success, error, timeout) |
||||
{ |
||||
var attrs = {xmlns: Strophe.NS.DISCO_INFO}; |
||||
if (node) |
||||
attrs.node = node; |
||||
|
||||
var info = $iq({from:this._connection.jid, |
||||
to:jid, type:'get'}).c('query', attrs); |
||||
this._connection.sendIQ(info, success, error, timeout); |
||||
}, |
||||
/** Function: items |
||||
* Items query |
||||
* |
||||
* Parameters: |
||||
* (Function) call_back |
||||
* (String) jid |
||||
* (String) node |
||||
*/ |
||||
items: function(jid, node, success, error, timeout) |
||||
{ |
||||
var attrs = {xmlns: Strophe.NS.DISCO_ITEMS}; |
||||
if (node) |
||||
attrs.node = node; |
||||
|
||||
var items = $iq({from:this._connection.jid, |
||||
to:jid, type:'get'}).c('query', attrs); |
||||
this._connection.sendIQ(items, success, error, timeout); |
||||
}, |
||||
|
||||
/** PrivateFunction: _buildIQResult |
||||
*/ |
||||
_buildIQResult: function(stanza, query_attrs) |
||||
{ |
||||
var id = stanza.getAttribute('id'); |
||||
var from = stanza.getAttribute('from'); |
||||
var iqresult = $iq({type: 'result', id: id}); |
||||
|
||||
if (from !== null) { |
||||
iqresult.attrs({to: from}); |
||||
} |
||||
|
||||
return iqresult.c('query', query_attrs); |
||||
}, |
||||
|
||||
/** PrivateFunction: _onDiscoInfo |
||||
* Called when receive info request |
||||
*/ |
||||
_onDiscoInfo: function(stanza) |
||||
{ |
||||
var node = stanza.getElementsByTagName('query')[0].getAttribute('node'); |
||||
var attrs = {xmlns: Strophe.NS.DISCO_INFO}; |
||||
if (node) |
||||
{ |
||||
attrs.node = node; |
||||
} |
||||
var iqresult = this._buildIQResult(stanza, attrs); |
||||
for (var i=0; i<this._identities.length; i++) |
||||
{ |
||||
var attrs = {category: this._identities[i].category, |
||||
type : this._identities[i].type}; |
||||
if (this._identities[i].name) |
||||
attrs.name = this._identities[i].name; |
||||
if (this._identities[i].lang) |
||||
attrs['xml:lang'] = this._identities[i].lang; |
||||
iqresult.c('identity', attrs).up(); |
||||
} |
||||
for (var i=0; i<this._features.length; i++) |
||||
{ |
||||
iqresult.c('feature', {'var':this._features[i]}).up(); |
||||
} |
||||
this._connection.send(iqresult.tree()); |
||||
return true; |
||||
}, |
||||
/** PrivateFunction: _onDiscoItems |
||||
* Called when receive items request |
||||
*/ |
||||
_onDiscoItems: function(stanza) |
||||
{ |
||||
var query_attrs = {xmlns: Strophe.NS.DISCO_ITEMS}; |
||||
var node = stanza.getElementsByTagName('query')[0].getAttribute('node'); |
||||
if (node) |
||||
{ |
||||
query_attrs.node = node; |
||||
var items = []; |
||||
for (var i = 0; i < this._items.length; i++) |
||||
{ |
||||
if (this._items[i].node == node) |
||||
{ |
||||
items = this._items[i].call_back(stanza); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
var items = this._items; |
||||
} |
||||
var iqresult = this._buildIQResult(stanza, query_attrs); |
||||
for (var i = 0; i < items.length; i++) |
||||
{ |
||||
var attrs = {jid: items[i].jid}; |
||||
if (items[i].name) |
||||
attrs.name = items[i].name; |
||||
if (items[i].node) |
||||
attrs.node = items[i].node; |
||||
iqresult.c('item', attrs).up(); |
||||
} |
||||
this._connection.send(iqresult.tree()); |
||||
return true; |
||||
} |
||||
}); |
@ -0,0 +1 @@ |
||||
Strophe.addConnectionPlugin("caps",{HASH:"sha-1",node:"http://strophe.im/strophejs/",_ver:"",_connection:null,_knownCapabilities:{},_jidVerIndex:{},init:function(conn){this._connection=conn;Strophe.addNamespace("CAPS","http://jabber.org/protocol/caps");if(!this._connection.disco){throw"Caps plugin requires the disco plugin to be installed."}this._connection.disco.addFeature(Strophe.NS.CAPS);this._connection.addHandler(this._delegateCapabilities.bind(this),Strophe.NS.CAPS)},generateCapsAttrs:function(){return{xmlns:Strophe.NS.CAPS,hash:this.HASH,node:this.node,ver:this.generateVer()}},generateVer:function(){if(this._ver!==""){return this._ver}var ver="",identities=this._connection.disco._identities.sort(this._sortIdentities),identitiesLen=identities.length,features=this._connection.disco._features.sort(),featuresLen=features.length;for(var i=0;i<identitiesLen;i++){var curIdent=identities[i];ver+=curIdent.category+"/"+curIdent.type+"/"+curIdent.lang+"/"+curIdent.name+"<"}for(var i=0;i<featuresLen;i++){ver+=features[i]+"<"}this._ver=b64_sha1(ver);return this._ver},getCapabilitiesByJid:function(jid){if(this._jidVerIndex[jid]){return this._knownCapabilities[this._jidVerIndex[jid]]}return null},_delegateCapabilities:function(stanza){var from=stanza.getAttribute("from"),c=stanza.querySelector("c"),ver=c.getAttribute("ver"),node=c.getAttribute("node");if(!this._knownCapabilities[ver]){return this._requestCapabilities(from,node,ver)}else{this._jidVerIndex[from]=ver}if(!this._jidVerIndex[from]||!this._jidVerIndex[from]!==ver){this._jidVerIndex[from]=ver}return true},_requestCapabilities:function(to,node,ver){if(to!==this._connection.jid){var id=this._connection.disco.info(to,node+"#"+ver);this._connection.addHandler(this._handleDiscoInfoReply.bind(this),Strophe.NS.DISCO_INFO,"iq","result",id,to)}return true},_handleDiscoInfoReply:function(stanza){var query=stanza.querySelector("query"),node=query.getAttribute("node").split("#"),ver=node[1],from=stanza.getAttribute("from");if(!this._knownCapabilities[ver]){var childNodes=query.childNodes,childNodesLen=childNodes.length;this._knownCapabilities[ver]=[];for(var i=0;i<childNodesLen;i++){var node=childNodes[i];this._knownCapabilities[ver].push({name:node.nodeName,attributes:node.attributes})}this._jidVerIndex[from]=ver}else{if(!this._jidVerIndex[from]||!this._jidVerIndex[from]!==ver){this._jidVerIndex[from]=ver}}return false},_sortIdentities:function(a,b){if(a.category>b.category){return 1}if(a.category<b.category){return -1}if(a.type>b.type){return 1}if(a.type<b.type){return -1}if(a.lang>b.lang){return 1}if(a.lang<b.lang){return -1}return 0}}); |
@ -0,0 +1 @@ |
||||
Strophe.addConnectionPlugin("disco",{_connection:null,_identities:[],_features:[],_items:[],init:function(conn){this._connection=conn;this._identities=[];this._features=[];this._items=[];conn.addHandler(this._onDiscoInfo.bind(this),Strophe.NS.DISCO_INFO,"iq","get",null,null);conn.addHandler(this._onDiscoItems.bind(this),Strophe.NS.DISCO_ITEMS,"iq","get",null,null)},addIdentity:function(category,type,name,lang){for(var i=0;i<this._identities.length;i++){if(this._identities[i].category==category&&this._identities[i].type==type&&this._identities[i].name==name&&this._identities[i].lang==lang){return false}}this._identities.push({category:category,type:type,name:name,lang:lang});return true},addFeature:function(var_name){for(var i=0;i<this._features.length;i++){if(this._features[i]==var_name){return false}}this._features.push(var_name);return true},removeFeature:function(var_name){for(var i=0;i<this._features.length;i++){if(this._features[i]===var_name){this._features.splice(i,1);return true}}return false},addItem:function(jid,name,node,call_back){if(node&&!call_back){return false}this._items.push({jid:jid,name:name,node:node,call_back:call_back});return true},info:function(jid,node,success,error,timeout){var attrs={xmlns:Strophe.NS.DISCO_INFO};if(node){attrs.node=node}var info=$iq({from:this._connection.jid,to:jid,type:"get"}).c("query",attrs);this._connection.sendIQ(info,success,error,timeout)},items:function(jid,node,success,error,timeout){var attrs={xmlns:Strophe.NS.DISCO_ITEMS};if(node){attrs.node=node}var items=$iq({from:this._connection.jid,to:jid,type:"get"}).c("query",attrs);this._connection.sendIQ(items,success,error,timeout)},_buildIQResult:function(stanza,query_attrs){var id=stanza.getAttribute("id");var from=stanza.getAttribute("from");var iqresult=$iq({type:"result",id:id});if(from!==null){iqresult.attrs({to:from})}return iqresult.c("query",query_attrs)},_onDiscoInfo:function(stanza){var node=stanza.getElementsByTagName("query")[0].getAttribute("node");var attrs={xmlns:Strophe.NS.DISCO_INFO};if(node){attrs.node=node}var iqresult=this._buildIQResult(stanza,attrs);for(var i=0;i<this._identities.length;i++){var attrs={category:this._identities[i].category,type:this._identities[i].type};if(this._identities[i].name){attrs.name=this._identities[i].name}if(this._identities[i].lang){attrs["xml:lang"]=this._identities[i].lang}iqresult.c("identity",attrs).up()}for(var i=0;i<this._features.length;i++){iqresult.c("feature",{"var":this._features[i]}).up()}this._connection.send(iqresult.tree());return true},_onDiscoItems:function(stanza){var query_attrs={xmlns:Strophe.NS.DISCO_ITEMS};var node=stanza.getElementsByTagName("query")[0].getAttribute("node");if(node){query_attrs.node=node;var items=[];for(var i=0;i<this._items.length;i++){if(this._items[i].node==node){items=this._items[i].call_back(stanza);break}}}else{var items=this._items}var iqresult=this._buildIQResult(stanza,query_attrs);for(var i=0;i<items.length;i++){var attrs={jid:items[i].jid};if(items[i].name){attrs.name=items[i].name}if(items[i].node){attrs.node=items[i].node}iqresult.c("item",attrs).up()}this._connection.send(iqresult.tree());return true}}); |
Loading…
Reference in new issue