2011-08-04 20:32:01 +00:00
|
|
|
// Copyright 2011 Mark Cavage, Inc. All rights reserved.
|
|
|
|
|
|
|
|
var assert = require('assert');
|
|
|
|
var util = require('util');
|
|
|
|
|
|
|
|
var asn1 = require('asn1');
|
|
|
|
|
|
|
|
var Control = require('../control');
|
|
|
|
var Protocol = require('../protocol');
|
|
|
|
|
|
|
|
var logStub = require('../log_stub');
|
|
|
|
|
|
|
|
///--- Globals
|
|
|
|
|
|
|
|
var Ber = asn1.Ber;
|
|
|
|
var BerReader = asn1.BerReader;
|
|
|
|
var BerWriter = asn1.BerWriter;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///--- API
|
|
|
|
|
|
|
|
/**
|
|
|
|
* LDAPMessage structure.
|
|
|
|
*
|
|
|
|
* @param {Object} options stuff.
|
|
|
|
*/
|
|
|
|
function LDAPMessage(options) {
|
|
|
|
if (!options || typeof(options) !== 'object')
|
|
|
|
throw new TypeError('options (object) required');
|
|
|
|
|
|
|
|
this.messageID = options.messageID || 0;
|
|
|
|
this.protocolOp = options.protocolOp || undefined;
|
|
|
|
this.controls = options.controls ? options.controls.slice(0) : [];
|
|
|
|
|
|
|
|
this.log4js = options.log4js || logStub;
|
|
|
|
|
|
|
|
var self = this;
|
|
|
|
this.__defineGetter__('id', function() { return self.messageID; });
|
|
|
|
this.__defineGetter__('dn', function() { return self._dn || ''; });
|
|
|
|
this.__defineGetter__('type', function() { return 'LDAPMessage'; });
|
|
|
|
this.__defineGetter__('json', function() {
|
|
|
|
var j = {
|
|
|
|
messageID: self.messageID,
|
|
|
|
protocolOp: self.type
|
|
|
|
};
|
|
|
|
j = self._json(j);
|
|
|
|
j.controls = self.controls;
|
|
|
|
return j;
|
|
|
|
});
|
|
|
|
this.__defineGetter__('log', function() {
|
|
|
|
if (!self._log)
|
|
|
|
self._log = self.log4js.getLogger(self.type);
|
|
|
|
return self._log;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
module.exports = LDAPMessage;
|
|
|
|
|
|
|
|
|
|
|
|
LDAPMessage.prototype.toString = function() {
|
|
|
|
return JSON.stringify(this.json);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
LDAPMessage.prototype.parse = function(data, length) {
|
|
|
|
if (!data || !Buffer.isBuffer(data))
|
|
|
|
throw new TypeError('data (buffer) required');
|
|
|
|
|
|
|
|
if (this.log.isTraceEnabled())
|
|
|
|
this.log.trace('parse: data=%s, len=%d', util.inspect(data), length);
|
|
|
|
|
|
|
|
var ber = new BerReader(data);
|
|
|
|
|
|
|
|
// Delegate off to the specific type to parse
|
|
|
|
this._parse(ber, length);
|
|
|
|
|
|
|
|
// Look for controls
|
2011-08-10 21:46:04 +00:00
|
|
|
if (ber.peek() === 0xa0) {
|
2011-08-04 20:32:01 +00:00
|
|
|
ber.readSequence();
|
|
|
|
var end = ber.offset + ber.length;
|
|
|
|
while (ber.offset < end) {
|
|
|
|
var c = new Control();
|
|
|
|
if (c.parse(ber))
|
|
|
|
this.controls.push(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.log.isTraceEnabled())
|
|
|
|
this.log.trace('Parsing done: %j', this.json);
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
LDAPMessage.prototype.toBer = function() {
|
|
|
|
var writer = new BerWriter();
|
|
|
|
writer.startSequence();
|
|
|
|
writer.writeInt(this.messageID);
|
|
|
|
|
2011-09-16 16:06:07 +00:00
|
|
|
writer.startSequence(this.protocolOp);
|
2011-08-04 20:32:01 +00:00
|
|
|
if (this._toBer)
|
|
|
|
writer = this._toBer(writer);
|
|
|
|
writer.endSequence();
|
2011-09-16 16:06:07 +00:00
|
|
|
|
|
|
|
if (this.controls && this.controls.length) {
|
|
|
|
writer.startSequence(0xa0);
|
|
|
|
this.controls.forEach(function(c) {
|
|
|
|
c.toBer(writer);
|
|
|
|
});
|
|
|
|
writer.endSequence();
|
|
|
|
}
|
|
|
|
|
2011-08-04 20:32:01 +00:00
|
|
|
writer.endSequence();
|
|
|
|
return writer.buffer;
|
|
|
|
};
|