WebSocket: remove verifyClient and check in upgrade request instead

This commit is contained in:
HF 2022-09-03 23:36:22 +02:00
parent d13c6d2fe7
commit bed2ae48e2
2 changed files with 30 additions and 28 deletions

View File

@ -45,13 +45,9 @@ function wsupgrade(request, socket, head) {
const { pathname } = url.parse(request.url); const { pathname } = url.parse(request.url);
if (pathname === '/ws') { if (pathname === '/ws') {
usersocket.wss.handleUpgrade(request, socket, head, (ws) => { usersocket.handleUpgrade(request, socket, head);
usersocket.wss.emit('connection', ws, request);
});
} else if (pathname === '/mcws') { } else if (pathname === '/mcws') {
apisocket.wss.handleUpgrade(request, socket, head, (ws) => { apisocket.handleUpgrade(request, socket, head);
apisocket.wss.emit('connection', ws, request);
});
} else { } else {
socket.destroy(); socket.destroy();
} }

View File

@ -55,7 +55,6 @@ class SocketServer {
constructor() { constructor() {
this.CHUNK_CLIENTS = new Map(); this.CHUNK_CLIENTS = new Map();
this.verifyClient = this.verifyClient.bind(this);
this.broadcast = this.broadcast.bind(this); this.broadcast = this.broadcast.bind(this);
this.broadcastPixelBuffer = this.broadcastPixelBuffer.bind(this); this.broadcastPixelBuffer = this.broadcastPixelBuffer.bind(this);
this.reloadUser = this.reloadUser.bind(this); this.reloadUser = this.reloadUser.bind(this);
@ -73,7 +72,6 @@ class SocketServer {
// path: "/ws", // path: "/ws",
// server, // server,
noServer: true, noServer: true,
verifyClient: this.verifyClient,
}); });
this.wss = wss; this.wss = wss;
@ -81,17 +79,13 @@ class SocketServer {
logger.error(`WebSocket Server Error ${e.message}`); logger.error(`WebSocket Server Error ${e.message}`);
}); });
wss.on('connection', async (ws, req) => { wss.on('connection', (ws, req) => {
ws.timeLastMsg = Date.now(); ws.timeLastMsg = Date.now();
ws.canvasId = null; ws.canvasId = null;
const user = await authenticateClient(req); const { user } = req;
if (!user) {
ws.close();
return;
}
ws.user = user; ws.user = user;
ws.chunkCnt = 0;
ws.name = user.getName(); ws.name = user.getName();
ws.chunkCnt = 0;
const { ip } = user; const { ip } = user;
isIPAllowed(ip); isIPAllowed(ip);
@ -178,29 +172,30 @@ class SocketServer {
setInterval(this.checkHealth, 15 * 1000); setInterval(this.checkHealth, 15 * 1000);
} }
verifyClient(info, done) { async handleUpgrade(request, socket, head) {
const { req } = info; const { headers } = request;
const { headers } = req;
// Limiting socket connections per ip // Limiting socket connections per ip
const ip = getIPFromRequest(req); const ip = getIPFromRequest(request);
// ratelimited
const now = Date.now(); const now = Date.now();
const limiter = rateLimit.get(ip); const limiter = rateLimit.get(ip);
if (limiter && limiter[1]) { if (limiter && limiter[1]) {
if (limiter[0] > now) { if (limiter[0] > now) {
// logger.info(`Rejected Socket-RateLimited Client ${ip}.`); // logger.info(`Rejected Socket-RateLimited Client ${ip}.`);
return done(false); socket.write('HTTP/1.1 429 Too Many Requests\r\n\r\n');
socket.destroy();
return;
} }
limiter[1] = false; limiter[1] = false;
logger.info(`Allow Socket-RateLimited Client ${ip} again.`); logger.info(`Allow Socket-RateLimited Client ${ip} again.`);
} }
// CORS // CORS
const { origin } = headers; const { origin } = headers;
if (!origin || !origin.endsWith(getHostFromRequest(req, false))) { if (!origin || !origin.endsWith(getHostFromRequest(request, false))) {
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
logger.info(`Rejected CORS request on websocket from ${ip} via ${headers.origin}, expected ${getHostFromRequest(req, false)}`); logger.info(`Rejected CORS request on websocket from ${ip} via ${headers.origin}, expected ${getHostFromRequest(request, false)}`);
return done(false); socket.write('HTTP/1.1 403 Forbidden\r\n\r\n');
socket.destroy();
return;
} }
if (ipCounter.get(ip) > 50) { if (ipCounter.get(ip) > 50) {
rateLimit.set(ip, [now + 1000 * 60 * 15, true]); rateLimit.set(ip, [now + 1000 * 60 * 15, true]);
@ -208,11 +203,22 @@ class SocketServer {
logger.info( logger.info(
`Client ${ip} has more than 50 connections open, killed ${amount}.`, `Client ${ip} has more than 50 connections open, killed ${amount}.`,
); );
return done(false); socket.write('HTTP/1.1 403 Forbidden\r\n\r\n');
socket.destroy();
return;
} }
ipCounter.add(ip); ipCounter.add(ip);
return done(true);
const user = await authenticateClient(request);
if (!user) {
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
socket.destroy();
return;
}
this.wss.handleUpgrade(request, socket, head, (ws) => {
this.wss.emit('connection', ws, request);
});
} }
/** /**
@ -532,7 +538,7 @@ class SocketServer {
retCode, retCode,
} = await drawByOffsets( } = await drawByOffsets(
ws.user, ws.user,
ws.canvasId, canvasId,
i, j, i, j,
pixels, pixels,
); );