1
0
Fork 0
mirror of https://gitlab.com/futo-org/fcast.git synced 2025-06-24 21:25:23 +00:00

Removal of encryption.,

This commit is contained in:
Koen 2023-12-30 11:28:36 +01:00
parent 9599c1931e
commit a991b353a6
16 changed files with 24 additions and 980 deletions

View file

@ -11,9 +11,7 @@
"dependencies": {
"bufferutil": "^4.0.8",
"https": "^1.0.0",
"node-forge": "^1.3.1",
"qrcode": "^1.5.3",
"tls": "^0.0.1",
"ws": "^8.14.2"
},
"devDependencies": {
@ -4309,14 +4307,6 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
"node_modules/node-forge": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
"engines": {
"node": ">= 6.13.0"
}
},
"node_modules/node-gyp-build": {
"version": "4.7.1",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.7.1.tgz",
@ -5158,11 +5148,6 @@
"node": ">=8"
}
},
"node_modules/tls": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/tls/-/tls-0.0.1.tgz",
"integrity": "sha512-GzHpG+hwupY8VMR6rYsnAhTHqT/97zT45PG8WD5eTT1lq+dFE0nN+1PYpsoBcHJgSmTz5ceK2Cv88IkPmIPOtQ=="
},
"node_modules/tmpl": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",

View file

@ -28,9 +28,7 @@
"dependencies": {
"bufferutil": "^4.0.8",
"https": "^1.0.0",
"node-forge": "^1.3.1",
"qrcode": "^1.5.3",
"tls": "^0.0.1",
"ws": "^8.14.2"
}
}

View file

@ -4,9 +4,7 @@ const os = require('os');
export class DiscoveryService {
private serviceTcp: any;
private serviceTls: any;
private serviceWs: any;
private serviceWss: any;
private static getComputerName() {
switch (process.platform) {
@ -23,7 +21,7 @@ export class DiscoveryService {
}
start() {
if (this.serviceTcp || this.serviceTls || this.serviceWs || this.serviceWss) {
if (this.serviceTcp || this.serviceWs) {
return;
}
@ -32,12 +30,8 @@ export class DiscoveryService {
this.serviceTcp = mdns.createAdvertisement(mdns.tcp('_fcast'), 46899, { name: name });
this.serviceTcp.start();
this.serviceTls = mdns.createAdvertisement(mdns.tcp('_fcast-tls'), 46897, { name: name });
this.serviceTls.start();
this.serviceWs = mdns.createAdvertisement(mdns.tcp('_fcast-ws'), 46898, { name: name });
this.serviceWs.start();
this.serviceWss = mdns.createAdvertisement(mdns.tcp('_fcast-wss'), 46896, { name: name });
this.serviceWss.start();
}
stop() {
@ -46,19 +40,9 @@ export class DiscoveryService {
this.serviceTcp = null;
}
if (this.serviceTls) {
this.serviceTls.stop();
this.serviceTls = null;
}
if (this.serviceWs) {
this.serviceWs.stop();
this.serviceWs = null;
}
if (this.serviceWss) {
this.serviceWss.stop();
this.serviceWss = null;
}
}
}

View file

@ -7,10 +7,6 @@ import { Updater } from './Updater';
import { WebSocketListenerService } from './WebSocketListenerService';
import * as os from 'os';
import { Opcode } from './FCastSession';
import fs = require('fs');
import forge = require('node-forge');
import { TlsListenerService } from './TlsTcpListenerService';
import { WebSocketSecureListenerService } from './WebSocketSecureListenerService';
export default class Main {
static shouldOpenMainWindow = true;
@ -19,8 +15,6 @@ export default class Main {
static application: Electron.App;
static tcpListenerService: TcpListenerService;
static webSocketListenerService: WebSocketListenerService;
static tlsListenerService: TlsListenerService;
static webSocketSecureListenerService: WebSocketSecureListenerService;
static discoveryService: DiscoveryService;
static tray: Tray;
static key: string = null;
@ -108,10 +102,8 @@ export default class Main {
Main.tcpListenerService = new TcpListenerService();
Main.webSocketListenerService = new WebSocketListenerService();
Main.tlsListenerService = new TlsListenerService(Main.key, Main.cert);
Main.webSocketSecureListenerService = new WebSocketSecureListenerService(Main.key, Main.cert);
const listeners = [Main.tcpListenerService, Main.webSocketListenerService, Main.tlsListenerService, Main.webSocketSecureListenerService];
const listeners = [Main.tcpListenerService, Main.webSocketListenerService];
listeners.forEach(l => {
l.emitter.on("play", (message) => {
if (Main.playerWindow == null) {
@ -234,50 +226,6 @@ export default class Main {
}
static main(app: Electron.App) {
if (!fs.existsSync('./cert.pem') || !fs.existsSync('./key.pem')) {
try {
const keys = forge.pki.rsa.generateKeyPair(2048);
const cert = forge.pki.createCertificate();
cert.publicKey = keys.publicKey;
cert.validity.notBefore = new Date();
cert.validity.notAfter = new Date(9999, 11, 31);
cert.sign(keys.privateKey);
const pemCert = forge.pki.certificateToPem(cert);
const pemKey = forge.pki.privateKeyToPem(keys.privateKey);
fs.writeFileSync('./cert.pem', pemCert);
fs.writeFileSync('./key.pem', pemKey);
} catch {
console.error("Failed to generate key pair.");
}
}
try {
Main.key = fs.readFileSync('./key.pem', 'utf8');
Main.cert = fs.readFileSync('./cert.pem', 'utf8');
} catch (e) {
console.error("Failed to load key pair.", e);
dialog.showMessageBox({
type: 'error',
title: 'Failed to initialize crypto',
message: `The application failed to start properly '${JSON.stringify(e)}'.`,
buttons: ['Restart', 'Close'],
defaultId: 0,
cancelId: 1
}).then((p) => {
if (p.response === 0) {
app.relaunch();
app.exit(0);
} else {
app.exit(0);
}
});
return;
}
Main.application = app;
const argv = process.argv;
if (argv.includes('--no-main-window')) {

View file

@ -1,105 +0,0 @@
import tls = require('tls');
import { FCastSession, Opcode } from './FCastSession';
import { EventEmitter } from 'node:events';
import { dialog } from 'electron';
import Main from './Main';
export class TlsListenerService {
public static PORT = 46897;
emitter = new EventEmitter();
private server: tls.Server;
private sessions: FCastSession[] = [];
constructor(private key: string, private cert: string) {}
start() {
if (this.server != null) {
return;
}
const options: tls.TlsOptions = {key: this.key, cert: this.cert};
this.server = tls.createServer(options).listen(TlsListenerService.PORT)
.on("secureConnection", this.handleConnection.bind(this))
.on("error", this.handleServerError.bind(this));
}
stop() {
if (this.server == null) {
return;
}
const server = this.server;
this.server = null;
server.close();
}
send(opcode: number, message = null) {
this.sessions.forEach(session => {
try {
session.send(opcode, message);
} catch (e) {
console.warn("Failed to send error.", e);
session.close();
}
});
}
private async handleServerError(err: NodeJS.ErrnoException) {
console.error("Server error:", err);
const restartPrompt = await dialog.showMessageBox({
type: 'error',
title: 'Failed to start',
message: 'The application failed to start properly.',
buttons: ['Restart', 'Close'],
defaultId: 0,
cancelId: 1
});
if (restartPrompt.response === 0) {
Main.application.relaunch();
Main.application.exit(0);
} else {
Main.application.exit(0);
}
}
private handleConnection(socket: tls.TLSSocket) {
console.log(`new secure connection from ${socket.remoteAddress}:${socket.remotePort}`);
const session = new FCastSession(socket, (data) => socket.write(data));
session.bindEvents(this.emitter);
this.sessions.push(session);
socket.on("error", (err) => {
console.warn(`Error from ${socket.remoteAddress}:${socket.remotePort}.`, err);
socket.destroy();
});
socket.on("data", buffer => {
try {
session.processBytes(buffer);
} catch (e) {
console.warn(`Error while handling packet from ${socket.remoteAddress}:${socket.remotePort}.`, e);
socket.end();
}
});
socket.on("close", () => {
const index = this.sessions.indexOf(session);
if (index != -1) {
this.sessions.splice(index, 1);
}
});
try {
console.log('Sending version');
session.send(Opcode.Version, {version: 2});
} catch (e) {
console.log('Failed to send version');
}
}
}

View file

@ -1,118 +0,0 @@
import { FCastSession, Opcode } from './FCastSession';
import { EventEmitter } from 'node:events';
import { dialog } from 'electron';
import Main from './Main';
import { WebSocket, WebSocketServer } from 'ws';
import * as https from 'https';
export class WebSocketSecureListenerService {
public static PORT = 46896;
emitter = new EventEmitter();
private server: WebSocketServer;
private sessions: FCastSession[] = [];
private httpsServer: https.Server;
constructor(private key: string, private cert: string) {}
start() {
if (this.server != null || this.httpsServer != null) {
return;
}
this.httpsServer = https.createServer({key: this.key, cert: this.cert});
this.httpsServer.listen(WebSocketSecureListenerService.PORT);
this.server = new WebSocketServer({server: this.httpsServer})
.on("connection", this.handleConnection.bind(this))
.on("error", this.handleServerError.bind(this));
}
stop() {
if (this.server != null) {
const server = this.server;
this.server = null;
server.close();
}
if (this.httpsServer != null) {
const httpsServer = this.httpsServer;
this.httpsServer = null;
httpsServer.close();
}
}
send(opcode: number, message = null) {
this.sessions.forEach(session => {
try {
session.send(opcode, message);
} catch (e) {
console.warn("Failed to send error.", e);
session.close();
}
});
}
private async handleServerError(err: NodeJS.ErrnoException) {
console.error("Server error:", err);
const restartPrompt = await dialog.showMessageBox({
type: 'error',
title: 'Failed to start',
message: 'The application failed to start properly.',
buttons: ['Restart', 'Close'],
defaultId: 0,
cancelId: 1
});
if (restartPrompt.response === 0) {
Main.application.relaunch();
Main.application.exit(0);
} else {
Main.application.exit(0);
}
}
private handleConnection(socket: WebSocket) {
console.log('New WebSocketSecure connection');
const session = new FCastSession(socket, (data) => socket.send(data));
session.bindEvents(this.emitter);
this.sessions.push(session);
socket.on("error", (err) => {
console.warn(`Error.`, err);
session.close();
});
socket.on('message', data => {
try {
if (data instanceof Buffer) {
session.processBytes(data);
} else {
console.warn("Received unhandled string message", data);
}
} catch (e) {
console.warn(`Error while handling packet.`, e);
session.close();
}
});
socket.on("close", () => {
console.log('WebSocketSecure connection closed');
const index = this.sessions.indexOf(session);
if (index != -1) {
this.sessions.splice(index, 1);
}
});
try {
console.log('Sending version');
session.send(Opcode.Version, {version: 2});
} catch (e) {
console.log('Failed to send version');
}
}
}

View file

@ -22,7 +22,7 @@
<div id="manual-connection-info">Manual connection information</div>
<div>
<div id="ips">IPs</div><br />
<div>Port<br>46899 (TCP), 46898 (WS), 46897 (TLS), 46896 (WSS)</div>
<div>Port<br>46899 (TCP), 46898 (WS)</div>
</div>
<div id="automatic-discovery">Automatic discovery is available via mDNS</div>
<div id="qr-code"></div>

View file

@ -24,8 +24,6 @@ window.electronAPI.onDeviceInfo((_event, value) => {
services: [
{ port: 46899, type: 0 }, //TCP
{ port: 46898, type: 1 }, //WS
{ port: 46897, type: 2 }, //TCP-TLS
{ port: 46896, type: 3 } //WSS
]
};