You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.4 KiB

import * as events from 'events';
import { openTLSSockets, startTLSServer } from '../tls/crypt';
import { IResponseHandlers } from '../types/Handler';
import { PAPChallenge } from './challenges/pap';
import { IEAPType } from '../types/EAPType';
export class EAPTTLS implements IEAPType {
papChallenge: PAPChallenge;
constructor(private sendEAPResponse) {
this.papChallenge = new PAPChallenge();
}
handleMessage(msg: Buffer, state: string, handlers, identifier: number) {
const flags = msg.slice(5, 6); // .toString('hex');
// if (flags)
// @todo check if "L" flag is set in flags
const msglength = msg.slice(6, 10).readInt32BE(0); // .toString('hex');
const data = msg.slice(6, msg.length); // 10); //.toString('hex');
// check if no data package is there and we have something in the queue, if so.. empty the queue first
if (!data) {
// @todo: queue processing
console.warn('no data, just a confirmation!');
return;
}
console.log('incoming EAP TTLS', {
flags /*
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| L | M | S | R | R | V |
+---+---+---+---+---+---+---+---+
L = Length included
M = More fragments
S = Start
R = Reserved
V = Version (000 for EAP-TTLSv0)
*/,
msglength,
data,
dataStr: data.toString()
});
let sslLayer = openTLSSockets.get(state) as
| { socket: events.EventEmitter; currentHandlers: IResponseHandlers }
| undefined;
if (!sslLayer) {
const newSocket = startTLSServer();
sslLayer = { socket: newSocket, currentHandlers: handlers };
openTLSSockets.set(state, sslLayer);
// register event listeners
newSocket.on('incoming', (incomingData: Buffer) => {
const type = incomingData.slice(3, 4).readUInt8(0);
// const code = data.slice(4, 5).readUInt8(0);
switch (type) {
case 1: // PAP / CHAP
try {
const { username, password } = this.papChallenge.decode(incomingData);
sslLayer!.currentHandlers.checkAuth(username, password, identifier);
} catch (err) {
// pwd not found..
console.error('pwd not found', err);
// NAK
this.sendEAPResponse(sslLayer!.currentHandlers.response, identifier, undefined, 3);
newSocket.emit('end');
throw new Error(`pwd not found`);
}
break;
default:
console.log('data', incomingData);
console.log('data str', incomingData.toString());
newSocket.emit('end');
throw new Error(`unsupported auth type${type}`);
}
});
newSocket.on('response', (responseData: Buffer) => {
console.log('sending encrypted data back to client', responseData);
// send back...
this.sendEAPResponse(sslLayer!.currentHandlers.response, identifier, responseData);
// this.sendMessage(TYPE.PRELOGIN, data, false);
});
newSocket.on('end', () => {
// cleanup socket
console.log('ENDING SOCKET');
openTLSSockets.del(state);
});
} else {
console.log('using existing socket');
}
// update handlers
sslLayer.currentHandlers = {
...handlers,
checkAuth: (username: string, password: string) =>
handlers.checkAuth(username, password, identifier)
};
// emit data to tls server
sslLayer.socket.emit('send', data);
}
}