mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-10-03 02:21:53 -04:00
Add incredibly hacky and broken secure websocket code behind SECURE_WEBSOCKETS
This commit is contained in:
parent
235eb3cdfd
commit
cb26d3c9e2
@ -18,6 +18,10 @@ using System.Net;
|
|||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Security;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
|
||||||
namespace MCGalaxy.Network {
|
namespace MCGalaxy.Network {
|
||||||
|
|
||||||
@ -53,7 +57,14 @@ namespace MCGalaxy.Network {
|
|||||||
} else if (opcode == 'G' && Server.Config.WebClient) {
|
} else if (opcode == 'G' && Server.Config.WebClient) {
|
||||||
pending.Remove(this);
|
pending.Remove(this);
|
||||||
return new WebSocket(this);
|
return new WebSocket(this);
|
||||||
} else {
|
}
|
||||||
|
#if SECURE_WEBSOCKETS
|
||||||
|
else if (opcode == 0x16 && Server.Config.WebClient) {
|
||||||
|
pending.Remove(this);
|
||||||
|
return new SecureSocket(this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
Logger.Log(LogType.UserActivity, "Disconnected {0} (unknown opcode {1})", IP, opcode);
|
Logger.Log(LogType.UserActivity, "Disconnected {0} (unknown opcode {1})", IP, opcode);
|
||||||
Close();
|
Close();
|
||||||
return null;
|
return null;
|
||||||
@ -251,7 +262,7 @@ namespace MCGalaxy.Network {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Abstracts a WebSocket on top of a TCP socket. </summary>
|
/// <summary> Abstracts a WebSocket on top of a socket. </summary>
|
||||||
public sealed class WebSocket : INetSocket, INetProtocol {
|
public sealed class WebSocket : INetSocket, INetProtocol {
|
||||||
readonly INetSocket s;
|
readonly INetSocket s;
|
||||||
|
|
||||||
@ -481,4 +492,100 @@ namespace MCGalaxy.Network {
|
|||||||
public void Disconnect() { Disconnect(1000); }
|
public void Disconnect() { Disconnect(1000); }
|
||||||
public override void Close() { s.Close(); }
|
public override void Close() { s.Close(); }
|
||||||
}
|
}
|
||||||
|
#if SECURE_WEBSOCKETS
|
||||||
|
public sealed class SecureSocket : INetSocket, INetProtocol {
|
||||||
|
readonly INetSocket raw;
|
||||||
|
WrapperStream wrapper;
|
||||||
|
SslStream ssl;
|
||||||
|
|
||||||
|
public SecureSocket(INetSocket socket) {
|
||||||
|
IP = socket.IP;
|
||||||
|
raw = socket;
|
||||||
|
|
||||||
|
wrapper = new WrapperStream();
|
||||||
|
wrapper.s = this;
|
||||||
|
|
||||||
|
ssl = new SslStream(wrapper);
|
||||||
|
new Thread(IOThread).Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init taken care by underlying socket
|
||||||
|
public override void Init() { }
|
||||||
|
public override bool LowLatency { set { raw.LowLatency = value; } }
|
||||||
|
public override void Close() { raw.Close(); }
|
||||||
|
public void Disconnect() { Close(); }
|
||||||
|
|
||||||
|
public override void Send(byte[] buffer, bool sync) { ssl.Write(buffer); }
|
||||||
|
public override void SendLowPriority(byte[] buffer) { ssl.Write(buffer); }
|
||||||
|
|
||||||
|
public int ProcessReceived(byte[] data, int count) {
|
||||||
|
lock (wrapper.locker) {
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
wrapper.input.Add(data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOThread() {
|
||||||
|
try {
|
||||||
|
// UGLY HACK I don't know what this file should even contain??? seems you need public and private key
|
||||||
|
X509Certificate2 cert = new X509Certificate2(Server.Config.SslCertPath, Server.Config.SslCertPass);
|
||||||
|
ssl.AuthenticateAsServer(cert);
|
||||||
|
|
||||||
|
Server.s.Log(".. reading player packets ..");
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
for (;;) {
|
||||||
|
int read = ssl.Read(buffer, 0, 4096);
|
||||||
|
if (read == 0) break;
|
||||||
|
this.HandleReceived(buffer, read);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.LogError("Error reading from secure stream", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UGLY HACK because can't derive from two base classes
|
||||||
|
sealed class WrapperStream : Stream {
|
||||||
|
public SecureSocket s;
|
||||||
|
public readonly object locker = new object();
|
||||||
|
public readonly List<byte> input = new List<byte>();
|
||||||
|
|
||||||
|
public override bool CanRead { get { return true; } }
|
||||||
|
public override bool CanSeek { get { return false; } }
|
||||||
|
public override bool CanWrite { get { return true; } }
|
||||||
|
|
||||||
|
static Exception ex = new NotSupportedException();
|
||||||
|
public override void Flush() { }
|
||||||
|
public override long Length { get { throw ex; } }
|
||||||
|
public override long Position { get { throw ex; } set { throw ex; } }
|
||||||
|
public override long Seek(long offset, SeekOrigin origin) { throw ex; }
|
||||||
|
public override void SetLength(long length) { throw ex; }
|
||||||
|
|
||||||
|
public override int Read(byte[] buffer, int offset, int count) {
|
||||||
|
// UGLY HACK wait until got some data
|
||||||
|
for (;;) {
|
||||||
|
lock (locker) { if (input.Count > 0) break; }
|
||||||
|
Thread.Sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now actually output the data
|
||||||
|
lock (locker) {
|
||||||
|
count = Math.Min(count, input.Count);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
buffer[offset++] = input[i];
|
||||||
|
}
|
||||||
|
input.RemoveRange(0, count);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(byte[] buffer, int offset, int count) {
|
||||||
|
byte[] data = new byte[count];
|
||||||
|
Buffer.BlockCopy(buffer, offset, data, 0, count);
|
||||||
|
s.raw.Send(data, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,13 @@ namespace MCGalaxy {
|
|||||||
public bool Public = false;
|
public bool Public = false;
|
||||||
[ConfigBool("verify-names", "Server", true)]
|
[ConfigBool("verify-names", "Server", true)]
|
||||||
public bool VerifyNames = true;
|
public bool VerifyNames = true;
|
||||||
|
|
||||||
[ConfigBool("support-web-client", "Server", true)]
|
[ConfigBool("support-web-client", "Server", true)]
|
||||||
public bool WebClient = true;
|
public bool WebClient = true;
|
||||||
|
[ConfigString("ssl-certificate-path", "Other", "", true)]
|
||||||
|
public string SslCertPath = "";
|
||||||
|
[ConfigString("ssl-certificate-password", "Other", "", true)]
|
||||||
|
public string SslCertPass = "";
|
||||||
|
|
||||||
[ConfigBool("autoload", "Server", true)]
|
[ConfigBool("autoload", "Server", true)]
|
||||||
public bool AutoLoadMaps = true;
|
public bool AutoLoadMaps = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user