using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.Xml; using Fleck; using InABox.Core; using Logger = InABox.Core.Logger; namespace InABox.Rpc; public class RpcSocketProxyServer : RpcProxyServer { private WebSocketServer? _server; public static X509Certificate2? Certificate { get; set; } //public static void InitCertificate(string certificateFile) => Certificate = new X509Certificate2(certificateFile); public override bool IsSecure() => Certificate != null; public RpcSocketProxyServer(int port, IRpcClientTransport serverTransport, X509Certificate2? certificate = null): base(serverTransport) { Certificate = certificate; var protocol = certificate != null ? "wss" : "ws"; _server = new WebSocketServer($"{protocol}://0.0.0.0:{port}"); if (Certificate != null) { /*_server.SslConfiguration.ServerCertificate = Certificate; _server.SslConfiguration.ClientCertificateRequired = false; _server.SslConfiguration.CheckCertificateRevocation = false; _server.SslConfiguration.ClientCertificateValidationCallback = WSSCallback; _server.SslConfiguration.EnabledSslProtocols = SslProtocols.Tls12;*/ _server.Certificate = Certificate; } /*_server?.AddWebSocketService("/", (connection) => { connection.Transport = this; //new RpcServerSocketConnection() { Transport = this }; });*/ } private bool WSSCallback(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslpolicyerrors) { return true; } public override void Start() { _server?.Start(socket => { var connection = new RpcServerSocketConnection2(socket); socket.OnOpen = () => ConnectionOpened(connection); socket.OnClose = () => ConnectionClosed(connection); socket.OnError = (e) => ConnectionException(connection, e); socket.OnBinary = (data) => Task.Run(() => { RpcMessage? request = Serialization.ReadBinary(data, BinarySerializationSettings.Latest); var response = DoMessage(connection, request); socket.Send(Serialization.WriteBinary(response, BinarySerializationSettings.Latest)); }); socket.OnMessage = (data) => Task.Run(() => { RpcMessage? request = Serialization.Deserialize(data); var response = DoMessage(connection, request); socket.Send(Serialization.Serialize(response)); }); }); } public override void Send(RpcServerSocketConnection2 connection, RpcMessage message) { connection.Connection.Send(Serialization.WriteBinary(message, BinarySerializationSettings.Latest)); } public override void Stop() { _server?.ListenerSocket.Close(); } public void ConnectionOpened(RpcServerSocketConnection2 connection) => DoOpen(connection); public void ConnectionException(RpcServerSocketConnection2 connection, Exception e) => DoException(connection, e); public void ConnectionClosed(RpcServerSocketConnection2 connection) => DoClose(connection, RpcTransportCloseEventType.Closed); }