|
|
@ -300,113 +300,120 @@ export class EAPTTLS implements IEAPMethod {
|
|
|
|
return {};
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.lastProcessedIdentifier.set(stateID, identifier);
|
|
|
|
this.lastProcessedIdentifier.set(stateID, identifier);
|
|
|
|
const { data } = this.decodeTTLSMessage(msg);
|
|
|
|
try {
|
|
|
|
|
|
|
|
const { data } = this.decodeTTLSMessage(msg);
|
|
|
|
// check if no data package is there and we have something in the queue, if so.. empty the queue first
|
|
|
|
|
|
|
|
if (!data || data.length === 0) {
|
|
|
|
// check if no data package is there and we have something in the queue, if so.. empty the queue first
|
|
|
|
const queuedData = this.queueData.get(stateID);
|
|
|
|
if (!data || data.length === 0) {
|
|
|
|
if (queuedData instanceof Buffer && queuedData.length > 0) {
|
|
|
|
const queuedData = this.queueData.get(stateID);
|
|
|
|
log(`returning queued data for ${stateID}`);
|
|
|
|
if (queuedData instanceof Buffer && queuedData.length > 0) {
|
|
|
|
return this.buildEAPTTLSResponse(identifier, 21, 0x00, stateID, queuedData, false);
|
|
|
|
log(`returning queued data for ${stateID}`);
|
|
|
|
|
|
|
|
return this.buildEAPTTLSResponse(identifier, 21, 0x00, stateID, queuedData, false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log(`empty data queue for ${stateID}`);
|
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
log(`empty data queue for ${stateID}`);
|
|
|
|
let connection = this.openTLSSockets.get(stateID) as ITLSServer;
|
|
|
|
return {};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let connection = this.openTLSSockets.get(stateID) as ITLSServer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!connection) {
|
|
|
|
if (!connection) {
|
|
|
|
connection = startTLSServer();
|
|
|
|
connection = startTLSServer();
|
|
|
|
this.openTLSSockets.set(stateID, connection);
|
|
|
|
this.openTLSSockets.set(stateID, connection);
|
|
|
|
|
|
|
|
|
|
|
|
connection.events.on('end', () => {
|
|
|
|
connection.events.on('end', () => {
|
|
|
|
// cleanup socket
|
|
|
|
// cleanup socket
|
|
|
|
log('ENDING SOCKET');
|
|
|
|
log('ENDING SOCKET');
|
|
|
|
this.openTLSSockets.del(stateID);
|
|
|
|
this.openTLSSockets.del(stateID);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const sendResponsePromise = newDeferredPromise();
|
|
|
|
const sendResponsePromise = newDeferredPromise();
|
|
|
|
|
|
|
|
|
|
|
|
const incomingMessageHandler = async (incomingData: Buffer) => {
|
|
|
|
const incomingMessageHandler = async (incomingData: Buffer) => {
|
|
|
|
const ret: any = {};
|
|
|
|
const ret: any = {};
|
|
|
|
ret.attributes = {};
|
|
|
|
ret.attributes = {};
|
|
|
|
ret.raw_attributes = [];
|
|
|
|
ret.raw_attributes = [];
|
|
|
|
|
|
|
|
|
|
|
|
const AVPs = this.decodeAVPs(incomingData);
|
|
|
|
const AVPs = this.decodeAVPs(incomingData);
|
|
|
|
|
|
|
|
|
|
|
|
// build attributes for packet handler
|
|
|
|
// build attributes for packet handler
|
|
|
|
const attributes: IPacketAttributes = {};
|
|
|
|
const attributes: IPacketAttributes = {};
|
|
|
|
AVPs.forEach((avp) => {
|
|
|
|
AVPs.forEach((avp) => {
|
|
|
|
attributes[attr_id_to_name(avp.type)] = avp.data;
|
|
|
|
attributes[attr_id_to_name(avp.type)] = avp.data;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
attributes.State = `${stateID}-inner`;
|
|
|
|
attributes.State = `${stateID}-inner`;
|
|
|
|
|
|
|
|
|
|
|
|
// handle incoming package via inner tunnel
|
|
|
|
// handle incoming package via inner tunnel
|
|
|
|
const result = await this.innerTunnel.handlePacket(
|
|
|
|
const result = await this.innerTunnel.handlePacket(
|
|
|
|
{
|
|
|
|
{
|
|
|
|
attributes,
|
|
|
|
attributes,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
this.getEAPType()
|
|
|
|
this.getEAPType()
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
log('inner tunnel result', result);
|
|
|
|
log('inner tunnel result', result);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
|
|
|
result.code === PacketResponseCode.AccessReject ||
|
|
|
|
|
|
|
|
result.code === PacketResponseCode.AccessAccept
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
sendResponsePromise.resolve(
|
|
|
|
|
|
|
|
this.authResponse(
|
|
|
|
|
|
|
|
identifier,
|
|
|
|
|
|
|
|
result.code === PacketResponseCode.AccessAccept,
|
|
|
|
|
|
|
|
connection.tls,
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
...packet,
|
|
|
|
|
|
|
|
attributes: {
|
|
|
|
|
|
|
|
...packet.attributes,
|
|
|
|
|
|
|
|
...this.transformAttributesArrayToMap(result.attributes),
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const eapMessage = result.attributes?.find((attr) => attr[0] === 'EAP-Message');
|
|
|
|
|
|
|
|
if (!eapMessage) {
|
|
|
|
|
|
|
|
throw new Error('no eap message found');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
connection.events.emit(
|
|
|
|
|
|
|
|
'encrypt',
|
|
|
|
|
|
|
|
this.buildAVP(attr_name_to_id('EAP-Message'), eapMessage[1] as Buffer)
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
const responseHandler = (encryptedResponseData: Buffer) => {
|
|
|
|
result.code === PacketResponseCode.AccessReject ||
|
|
|
|
// send back...
|
|
|
|
result.code === PacketResponseCode.AccessAccept
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
sendResponsePromise.resolve(
|
|
|
|
sendResponsePromise.resolve(
|
|
|
|
this.authResponse(
|
|
|
|
this.buildEAPTTLSResponse(identifier, 21, 0x00, stateID, encryptedResponseData)
|
|
|
|
identifier,
|
|
|
|
|
|
|
|
result.code === PacketResponseCode.AccessAccept,
|
|
|
|
|
|
|
|
connection.tls,
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
...packet,
|
|
|
|
|
|
|
|
attributes: {
|
|
|
|
|
|
|
|
...packet.attributes,
|
|
|
|
|
|
|
|
...this.transformAttributesArrayToMap(result.attributes),
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
);
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const eapMessage = result.attributes?.find((attr) => attr[0] === 'EAP-Message');
|
|
|
|
|
|
|
|
if (!eapMessage) {
|
|
|
|
|
|
|
|
throw new Error('no eap message found');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
connection.events.emit(
|
|
|
|
|
|
|
|
'encrypt',
|
|
|
|
|
|
|
|
this.buildAVP(attr_name_to_id('EAP-Message'), eapMessage[1] as Buffer)
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const responseHandler = (encryptedResponseData: Buffer) => {
|
|
|
|
|
|
|
|
// send back...
|
|
|
|
|
|
|
|
sendResponsePromise.resolve(
|
|
|
|
|
|
|
|
this.buildEAPTTLSResponse(identifier, 21, 0x00, stateID, encryptedResponseData)
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// register event listeners
|
|
|
|
// register event listeners
|
|
|
|
connection.events.on('incoming', incomingMessageHandler);
|
|
|
|
connection.events.on('incoming', incomingMessageHandler);
|
|
|
|
connection.events.on('response', responseHandler);
|
|
|
|
connection.events.on('response', responseHandler);
|
|
|
|
|
|
|
|
|
|
|
|
// emit data to tls server
|
|
|
|
// emit data to tls server
|
|
|
|
connection.events.emit('decrypt', data);
|
|
|
|
connection.events.emit('decrypt', data);
|
|
|
|
const responseData = await sendResponsePromise.promise;
|
|
|
|
const responseData = await sendResponsePromise.promise;
|
|
|
|
|
|
|
|
|
|
|
|
// cleanup
|
|
|
|
// cleanup
|
|
|
|
connection.events.off('incoming', incomingMessageHandler);
|
|
|
|
connection.events.off('incoming', incomingMessageHandler);
|
|
|
|
connection.events.off('response', responseHandler);
|
|
|
|
connection.events.off('response', responseHandler);
|
|
|
|
|
|
|
|
|
|
|
|
// send response
|
|
|
|
// send response
|
|
|
|
return responseData; // this.buildEAPTTLSResponse(identifier, 21, 0x00, stateID, encryptedResponseData);
|
|
|
|
return responseData; // this.buildEAPTTLSResponse(identifier, 21, 0x00, stateID, encryptedResponseData);
|
|
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
|
|
console.error('decoding of EAP-TTLS package failed', msg, err);
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
code: PacketResponseCode.AccessReject,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private transformAttributesArrayToMap(attributes: [string, Buffer | string][] | undefined) {
|
|
|
|
private transformAttributesArrayToMap(attributes: [string, Buffer | string][] | undefined) {
|
|
|
|