[Pkg-javascript-commits] [ltx] 02/469: SASL PLAIN, bind & session
Jonas Smedegaard
dr at jones.dk
Wed Aug 31 13:00:49 UTC 2016
This is an automated email from the git hooks/post-receive script.
js pushed a commit to branch master
in repository ltx.
commit 29612d1a34c5ac676178809528231692bd62ef3c
Author: Astro <astro at spaceboyz.net>
Date: Wed May 26 03:26:56 2010 +0200
SASL PLAIN, bind & session
---
lib/xmpp/connection.js | 117 ++++++++++++++++++++++++++++++++++++++++++++++---
lib/xmpp/jid.js | 18 +++++++-
lib/xmpp/sasl.js | 16 +++++++
3 files changed, 144 insertions(+), 7 deletions(-)
diff --git a/lib/xmpp/connection.js b/lib/xmpp/connection.js
index 245bb3a..cc0371a 100644
--- a/lib/xmpp/connection.js
+++ b/lib/xmpp/connection.js
@@ -3,13 +3,30 @@ var sys = require('sys');
var expat = require('expat');
var puts = require('sys').puts;
var xml = require('./xml');
+var sasl = require('./sasl');
+var JID = require('./jid').JID;
+var b64 = require('base64');
var NS_XMPP_TLS = 'urn:ietf:params:xml:ns:xmpp-tls';
+var NS_XMPP_SASL = 'urn:ietf:params:xml:ns:xmpp-sasl';
+var NS_XMPP_BIND = 'urn:ietf:params:xml:ns:xmpp-bind';
+var NS_XMPP_SESSION = 'urn:ietf:params:xml:ns:xmpp-session';
+
+var STATE_PREAUTH = 0,
+ STATE_AUTH = 1,
+ STATE_AUTHED = 2,
+ STATE_BIND = 3,
+ STATE_SESSION = 4,
+ STATE_ONLINE = 5;
+var IQID_SESSION = 'sess',
+ IQID_BIND = 'bind';
function Connection() {
net.Stream.call(this);
+ this.state = STATE_PREAUTH;
this.charset = 'UTF-8';
+ this.allowTLS = true; /* can be set by user */
this.addListener('connect', this.startStream);
this.addListener('data', this.onData);
// this.addListener('end', this.onEnd);
@@ -20,6 +37,7 @@ sys.inherits(Connection, net.Stream);
exports.Connection = Connection;
Connection.prototype.send = function(stanza) {
+ puts("SEND " + stanza);
var self = this;
if (stanza.root)
stanza.root().write(function(s) {
@@ -49,7 +67,7 @@ Connection.prototype.startParser = function() {
});
self.parser.addListener('endElement', function(name, attrs) {
if (!self.element && name == 'stream:stream') {
- self.close();
+ self.end();
} else if (self.element && name == self.element.name) {
if (self.element.parent)
self.element = self.element.parent;
@@ -97,14 +115,101 @@ Connection.prototype.onData = function(data) {
Connection.prototype.onStanza = function(stanza) {
puts('Stanza: ' + stanza.toString());
- if (stanza.name == 'stream:features') {
- if (stanza.getChild('starttls', NS_XMPP_TLS)) {
+ if (this.state == STATE_ONLINE) {
+ this.emit('stanza', this.element);
+ } else if (this.state == STATE_PREAUTH &&
+ stanza.name == 'stream:features') {
+ if (this.allowTLS &&
+ stanza.getChild('starttls', NS_XMPP_TLS)) {
this.send(new xml.Element('starttls', { xmlns: NS_XMPP_TLS }));
+ } else if (stanza.getChild('mechanisms', NS_XMPP_SASL)) {
+ this.state = STATE_AUTH;
+ var mechs = stanza.getChild('mechanisms', NS_XMPP_SASL).
+ getChildren('mechanism', NS_XMPP_SASL).
+ map(function(el) { return el.getText(); });
+ var mech = selectAuthMechanism(mechs);
+ if (mech) {
+ mech.authzid = this.jid.bare().toString();
+ mech.authcid = this.jid.user;
+ mech.password = this.password;
+ this.send(new xml.Element('auth',
+ { xmlns: NS_XMPP_SASL,
+ mechanism: mech.name
+ }).t(b64.encode(mech.auth())));
+ } else {
+ this.emit('authFail');
+ this.end();
+ }
}
- } else if (stanza.name == 'proceed' && stanza.getNS() == NS_XMPP_TLS) {
+ } else if (stanza.name == 'proceed' &&
+ stanza.getNS() == NS_XMPP_TLS) {
this.setSecure();
this.addListener('secure', this.startStream);
- }
+ } else if (this.state == STATE_AUTH &&
+ stanza.getNS() == NS_XMPP_SASL) {
+ if (stanza.name == 'success') {
+ this.state = STATE_AUTHED;
+ this.startStream();
+ } else {
+ this.emit('authFail');
+ this.end();
+ }
+ } else if (this.state == STATE_AUTHED &&
+ stanza.name == 'stream:features' &&
+ stanza.getChild('bind', NS_XMPP_BIND)) {
+ this.state = STATE_BIND;
+ var bindEl = new xml.Element('iq',
+ { type: 'set',
+ id: IQID_BIND
+ }).c('bind',
+ { xmlns: NS_XMPP_BIND
+ });
+ if (this.jid.resource)
+ bindEl.c('resource').t(this.jid.resource);
+ this.send(bindEl.root());
+ } else if (this.state == STATE_BIND &&
+ stanza.name == 'iq' &&
+ stanza.attrs.id == IQID_BIND) {
+ if (stanza.attrs.type == 'result') {
+ this.state = STATE_AUTHED;
+ var bindEl = stanza.getChild('bind', NS_XMPP_BIND);
+ if (bindEl && bindEl.getChild('jid')) {
+ this.jid = new JID(bindEl.getChild('jid').getText());
+ }
- this.emit('stanza', this.element);
+ // FIXME: move this to check stream:features again
+ this.state = STATE_SESSION;
+ this.send(new xml.Element('iq',
+ { type: 'set',
+ to: this.jid.domain,
+ id: IQID_SESSION
+ }).c('session',
+ { xmlns: NS_XMPP_SESSION
+ }));
+ } else {
+ this.emit('error', "Cannot bind resource");
+ this.end();
+ }
+ } else if (this.state == STATE_SESSION &&
+ stanza.name == 'iq' &&
+ stanza.attrs.id == IQID_SESSION) {
+ if (stanza.attrs.type == 'result') {
+ this.state = STATE_AUTHED;
+ } else {
+ this.emit('error', "Cannot establish session");
+ this.end();
+ }
+ } else if (stanza.name == 'stream:error') {
+ this.emit('error', stanza);
+ this.end();
+ }
};
+
+function selectAuthMechanism(mechs) {
+ /*if (mechs.indexOf("DIGEST-MD5") >= 0)
+ return "DIGEST-MD5";
+ else*/ if (mechs.indexOf("PLAIN") >= 0)
+ return new sasl.Mechanism("PLAIN");
+ else
+ return null;
+}
diff --git a/lib/xmpp/jid.js b/lib/xmpp/jid.js
index b5e43d3..d2bcf95 100644
--- a/lib/xmpp/jid.js
+++ b/lib/xmpp/jid.js
@@ -18,6 +18,22 @@ JID.prototype.parseJID = function(s) {
s = s.substr(0, s.indexOf('/'));
}
this.domain = s;
-}
+};
+
+JID.prototype.toString = function() {
+ var s = this.domain;
+ if (this.user)
+ s = this.user + '@' + s;
+ if (this.resource)
+ s = s + '/' + this.resource;
+ return s;
+};
+
+JID.prototype.bare = function() {
+ if (this.resource)
+ return new JID(this.user, this.domain, null);
+ else
+ return this;
+};
exports.JID = JID;
diff --git a/lib/xmpp/sasl.js b/lib/xmpp/sasl.js
new file mode 100644
index 0000000..d215cc4
--- /dev/null
+++ b/lib/xmpp/sasl.js
@@ -0,0 +1,16 @@
+function Mechanism(name) {
+ this.name = name;
+ if (name == "PLAIN")
+ Plain.call(this);
+ else
+ throw("Unsupported mechanism: " + name);
+}
+exports.Mechanism = Mechanism;
+
+function Plain() {
+ this.auth = function() {
+ return this.authzid + "\0" +
+ this.authcid + "\0" +
+ this.password;
+ };
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/ltx.git
More information about the Pkg-javascript-commits
mailing list