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
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);
|
|
}
|
|
}
|