1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
using System;
using System.Linq;
using Fleck2;
using Fleck2.Interfaces;
namespace KeePassRPC
{
public class KeePassRPCServer
{
private static KeePassRPCService Service;
private KeePassRPCExt KeePassRPCPlugin;
private WebSocketServer _webSocketServer;
private static WebSocketServerConfig WebsocketConfig;
private void FleckLogger(LogLevel ll, string s, Exception e)
{
if (KeePassRPCPlugin.logger != null)
try
{
KeePassRPCPlugin.logger.WriteLine("Fleck says: " + s + (e != null ? (". Exception: " + e) : ""));
}
catch (Exception)
{
// Don't care
}
}
private void StartWebsockServer(WebSocketServerConfig config)
{
FleckLog.Level = LogLevel.Debug;
FleckLog.LogAction = FleckLogger;
// Fleck library changed behaviour with recent .NET versions so we have to supply the port in the location string
_webSocketServer = new WebSocketServer("ws://localhost:" + config.WebSocketPort, config.BindOnlyToLoopback);
Action<IWebSocketConnection> applyConfiguration = InitSocket;
_webSocketServer.Start(applyConfiguration);
}
private void InitSocket(IWebSocketConnection socket)
{
socket.OnOpen = delegate
{
// Immediately reject connections with unexpected origins
if (!ValidateOrigin(socket.ConnectionInfo.Origin)) {
if (KeePassRPCPlugin.logger != null) {
try
{
KeePassRPCPlugin.logger.WriteLine(socket.ConnectionInfo.Origin + " is not permitted to access KeePassRPC.");
}
catch (Exception)
{
// Don't care
}
}
} else {
KeePassRPCPlugin.AddRPCClientConnection(socket);
}
};
socket.OnClose = delegate
{
KeePassRPCPlugin.RemoveRPCClientConnection(socket);
};
socket.OnMessage = delegate (string message)
{
KeePassRPCPlugin.MessageRPCClientConnection(socket, message, Service);
};
}
private bool ValidateOrigin(string origin)
{
if (WebsocketConfig.PermittedOrigins.Any(o => origin.StartsWith(o))) {
return true;
}
return false;
}
/// <summary>
/// Starts the web socket listener
/// </summary>
/// <param name="service">The KeePassRPCService the server should interact with.</param>
public KeePassRPCServer(KeePassRPCService service, KeePassRPCExt keePassRPCPlugin, WebSocketServerConfig websocketConfig)
{
if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Starting KPRPCServer");
Service = service;
KeePassRPCPlugin = keePassRPCPlugin;
WebsocketConfig = websocketConfig;
StartWebsockServer(websocketConfig);
if (keePassRPCPlugin.logger != null) keePassRPCPlugin.logger.WriteLine("Started KPRPCServer");
}
}
}
|