Skip to content
Browse files

Added starttls and auth support

  • Loading branch information...
1 parent 0ed0b54 commit 23918c28e38b660c2b6dedf52ef2f3f0d3d28ce4 @snsparrish snsparrish committed Dec 28, 2012
Showing with 72 additions and 20 deletions.
  1. +5 −2 index.js
  2. +67 −18 lib/server/proto.js
View
7 index.js
@@ -38,8 +38,11 @@ exports.connect = function () {
else if (tlsOpts) {
stream = tls.connect(port, host, tlsOpts, function () {
var pending = stream.listeners('secure').length;
- var allOk = pending === 0 ? stream.authorized : true;
- if (pending === 0) done()
+ var allOk = true;
+ if(pending === 0){
+ if(!stream.authorized && tlsOpts.rejectUnauthorized !== false) allOk = false;
+ done();
+ }
else {
var ack = {
accept : function (ok) {
View
85 lib/server/proto.js
@@ -1,6 +1,7 @@
var parser = require('./parser');
var EventEmitter = require('events').EventEmitter;
var dot = require('../dot.js').dot;
+var crypto = require("crypto");
module.exports = function (stream) {
return new Client(stream);
@@ -55,32 +56,80 @@ Client.prototype.ehlo = function (hostname, cb) {
};
Client.prototype.starttls = function (cb) {
- if (typeof hostname === 'function') {
- cb = hostname;
- hostname = undefined;
- }
this.stream.write(
'STARTTLS'
+ '\r\n'
);
- this.queue.push(function(err,code,lines){
- // Upgrade connection to TLS
- if(err){
- cb(err, code, lines);
+ this.queue.push(cb);
+};
+
+Client.prototype.tlsconnectionupgrade = function (hostname, cb) { // hostname is required for cert check
+ var tls = require('tls');
+ var s = tls.connect({servername:hostname, socket:this.stream}, function(error, response){
+ if(error){
+ cb('Unable to upgrade connection',451);
return true;
}
- if(code == 220){
- var clear = require('./starttls').starttls(Client.stream, false, function() {
- if (!clear.authorized)
- cb(new Error('STARTTLS: failed to secure stream'));
- else {
- cb(false, 220,'STARTTLS success', clear);
+ cb(null,220,s);
+ });
+};
+
+Client.prototype.login = function (username, password, type, cb) {
+ var self = this;
+ var supportedTypes = ['PLAIN','LOGIN','CRAM-MD5'];
+ type = (type) ? type.toUpperCase() : 'PLAIN';
+ if(supportedTypes.indexOf(type) < 0){
+ cb('Unsupported login type', 451);
+ }
+ switch(type){
+ case 'PLAIN':
+ var buf = new Buffer(username + "\0" + username + "\0" + password);
+ self.stream.write("AUTH PLAIN " + buf.toString("base64") + "\r\n");
+ self.queue.push(cb);
+ break;
+ case "LOGIN":
+ case "CRAM-MD5":
+ self.authtype = type;
+ self.username = username;
+ self.password = password;
+ self.stream.write("AUTH " + type + "\r\n");
+ self.queue.push(function(err,code,lines){
+ if(err){
+ cb(err,code,lines);
+ return true;
+ }
+ if(code != 334){
+ cb(type+' Auth Failed',code,lines);
+ return true;
+ }
+ switch (self.authtype) {
+ case "LOGIN":
+ var buf = new Buffer(self.username);
+ self.stream.write(buf.toString("base64") + "\r\n");
+ self.queue.push(function(erro,code,lines){
+ if(erro){
+ cb(erro,code,lines);
+ return true;
+ }
+ if(code != 334){
+ cb('LOGIN Auth Failed at username',code,lines);
+ return true;
+ }
+ var buf = new Buffer(self.password);
+ self.stream.write(buf.toString("base64") + "\r\n");
+ self.queue.push(cb);
+ });
+ break;
+ case "CRAM-MD5":
+ var hmac = crypto.createHmac('md5', self.password);
+ msg = (new Buffer(msg, "base64")).toString("ascii");
+ hmac.update(msg);
+ self.stream.write((new Buffer(self.username + " " + hmac.digest("hex")).toString("base64")) + "\r\n");
+ self.queue.push(cb);
+ break;
}
});
- }else{
- cb('Unable to STARTTLS', code, lines);
- }
- });
+ }
};
Client.prototype.to = function (addr, ext, cb) {

0 comments on commit 23918c2

Please sign in to comment.
Something went wrong with that request. Please try again.