public void Start(int PacketSize, int Timeout) { Client.ClientDisconnecting += ClientClientDisconnecting; SocksEncryption w = null; if (Client == null) { this.Dispose(); return; } Authenticated = AuthenticateConnection(ref w); //Request Site Data. if (Authenticated == 1) { w = new SocksEncryption(); w.SetType(AuthTypes.Login); SocksRequest req = Socks5.RequestTunnel(this, w); if (req == null) { Client.Disconnect(); return; } req1 = new SocksRequest(req.StreamType, req.Type, req.Address, req.Port); //call on plugins for connect callbacks. foreach (ConnectHandler conn in PluginLoader.LoadPlugin(typeof(ConnectHandler))) if (conn.Enabled) if (conn.OnConnect(req1) == false) { req.Error = SocksError.Failure; Client.Send(req.GetData(true)); Client.Disconnect(); return; } //Send Tunnel Data back. SocksTunnel x = new SocksTunnel(this, req, req1, PacketSize, Timeout); x.TunnelDisposing += x_TunnelDisposing; x.Open(); } else if (Authenticated == 2) { SocksRequest req = Socks5.RequestTunnel(this, w); if (req == null) { Client.Disconnect(); return; } req1 = new SocksRequest(req.StreamType, req.Type, req.Address, req.Port); if (PluginLoader.LoadPlugin(typeof(ConnectHandler)).Cast<ConnectHandler>().Where(conn => conn.Enabled).Any(conn => conn.OnConnect(req1) == false)) { req.Error = SocksError.Failure; Client.Send(req.GetData(true)); Client.Disconnect(); return; } //Send Tunnel Data back. SocksSpecialTunnel x = new SocksSpecialTunnel(this, w, req, req1, PacketSize, Timeout); x.TunnelDisposing += x_TunnelDisposing; x.Start(); } }
public SocksSpecialTunnel(SocksClient p, SocksEncryption ph, SocksRequest req, SocksRequest req1, int packetSize, int timeout) { RemoteClient = new Client(new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp), PacketSize); Client = p; Req = req; ModifiedReq = req1; PacketSize = packetSize; Timeout = timeout; se = ph; isDisposing = false; }
public static SocksError SendRequest(Client cli, SocksEncryption enc, string ipOrDomain, int port) { AddressType type; IPAddress ipAddress; if (!IPAddress.TryParse(ipOrDomain, out ipAddress)) //it's a domain. :D (hopefully). type = AddressType.Domain; else type = AddressType.IP; SocksRequest sr = new SocksRequest(StreamTypes.Stream, type, ipOrDomain, port); //send data. byte[] p = sr.GetData(false); p[1] = 0x01; //process data. cli.Send(enc.ProcessOutputData(p, 0, p.Length)); byte[] buffer = new byte[512]; //process input data. int recv = cli.Receive(buffer, 0, buffer.Length); if(recv == -1) { return SocksError.Failure; } byte[] buff = enc.ProcessInputData(buffer, 0, recv); return (SocksError)buff[1]; }
public static SocksRequest RequestTunnel(SocksClient client, SocksEncryption ph) { byte[] data; int recv = Receive(client.Client, out data); byte[] buff = ph.ProcessInputData(data, 0, recv); if (buff == null || (HeaderTypes)buff[0] != HeaderTypes.Socks5) return null; switch ((StreamTypes)buff[1]) { case StreamTypes.Stream: { int fwd = 4; StringBuilder address = new StringBuilder(); switch ((AddressType)buff[3]) { case AddressType.IP: { for (int i = 4; i < 8; i++) { //grab IP. address.Append(Convert.ToInt32(buff[i]).ToString() + (i != 7 ? "." : "")); } fwd += 4; } break; case AddressType.Domain: { int domainlen = Convert.ToInt32(buff[4]); address.Append(Encoding.ASCII.GetString(buff, 5, domainlen)); fwd += domainlen + 1; } break; case AddressType.IPv6: //can't handle IPV6 traffic just yet. return null; } byte[] po = new byte[2]; Array.Copy(buff, fwd, po, 0, 2); Int16 x = BitConverter.ToInt16(po, 0); int port = Convert.ToInt32(IPAddress.NetworkToHostOrder(x)); port = (port < 1 ? port + 65536 : port); return new SocksRequest(StreamTypes.Stream, (AddressType)buff[3], address.ToString(), port); } default: //not supported. return null; } }
public static SocksEncryption RequestSpecialMode(List<AuthTypes> auth, Client client) { //select mode, do key exchange if encryption, or start compression. if (auth.Contains(AuthTypes.SocksBoth)) { //tell client that we chose socksboth. client.Send(new byte[] { (byte)HeaderTypes.Socks5, (byte)AuthTypes.SocksBoth }); //wait for public key. SocksEncryption ph = new SocksEncryption(); ph.GenerateKeys(); //wait for public key. byte[] buffer = new byte[4096]; int keysize = client.Receive(buffer, 0, buffer.Length); //store key in our encryption class. ph.SetKey(buffer, 0, keysize); //send key. client.Send(ph.GetPublicKey()); //now we give them our key. client.Send(ph.ShareEncryptionKey()); //send more. int enckeysize = client.Receive(buffer, 0, buffer.Length); //decrypt with our public key. byte[] newkey = new byte[enckeysize]; Buffer.BlockCopy(buffer, 0, newkey, 0, enckeysize); ph.SetEncKey(ph.key.Decrypt(newkey, false)); ph.SetType(AuthTypes.SocksBoth); //ready up our client. return ph; } else if (auth.Contains(AuthTypes.SocksEncrypt)) { //tell client that we chose socksboth. client.Send(new byte[] { (byte)HeaderTypes.Socks5, (byte)AuthTypes.SocksEncrypt }); //wait for public key. SocksEncryption ph = new SocksEncryption(); ph.GenerateKeys(); //wait for public key. byte[] buffer = new byte[4096]; int keysize = client.Receive(buffer, 0, buffer.Length); //store key in our encryption class. ph.SetKey(buffer, 0, keysize); ph.SetType(AuthTypes.SocksBoth); //ready up our client. return ph; } else if (auth.Contains(AuthTypes.SocksCompress)) { //start compression. client.Send(new byte[] { (byte)HeaderTypes.Socks5, (byte)AuthTypes.SocksCompress }); SocksEncryption ph = new SocksEncryption(); ph.SetType(AuthTypes.SocksCompress); //ready } else if (auth.Contains(AuthTypes.Login)) { SocksEncryption ph = new SocksEncryption(); ph.SetType(AuthTypes.Login); return ph; } return null; }
public int AuthenticateConnection(ref SocksEncryption encryption) { List<AuthTypes> authtypes = Socks5.RequestAuth(this); if (authtypes.Count <= 0) { Client.Send(new byte[] { 0x00, 0xFF }); Console.WriteLine("Client Request ERROR"); Client.Disconnect(); return 0; } this.Authenticated = 0; List<object> lhandlers = PluginLoader.LoadPlugin(typeof(LoginHandler)); bool loginenabled = false; if (lhandlers.Count > 0) { loginenabled = lhandlers.Cast<LoginHandler>().Any(l => l.Enabled); } //check out different auth types, none will have no authentication, the rest do. if (loginenabled && (authtypes.Contains(AuthTypes.SocksBoth) || authtypes.Contains(AuthTypes.SocksEncrypt) || authtypes.Contains(AuthTypes.SocksCompress) || authtypes.Contains(AuthTypes.Login))) { //this is the preferred method. encryption = Socks5.RequestSpecialMode(authtypes, Client); foreach (LoginHandler lh in lhandlers) { if (lh.Enabled) { //request login. User user = Socks5.RequestLogin(this); if (user == null) { Client.Disconnect(); return 0; } LoginStatus status = lh.HandleLogin(user); Client.Send(new byte[] { (byte)HeaderTypes.Socks5, (byte)status }); if (status == LoginStatus.Denied) { Console.WriteLine("> Login Denied!"); Client.Disconnect(); return 0; } else if (status == LoginStatus.Correct) { Authenticated = (encryption.GetAuthType() == AuthTypes.Login ? 1 : 2); break; } } } } else if (authtypes.Contains(AuthTypes.None)) { //no authentication. if (lhandlers.Count <= 1) { //unsupported methods y0 Authenticated = 1; Client.Send(new byte[] { (byte)HeaderTypes.Socks5, (byte)HeaderTypes.Zero }); } else { //unsupported. Client.Send(new byte[] { (byte)HeaderTypes.Socks5, (byte)AuthTypes.Unsupported }); Client.Disconnect(); return 0; } } else { //unsupported. Client.Send(new byte[] { (byte)HeaderTypes.Socks5, (byte)AuthTypes.Unsupported }); Client.Disconnect(); return 0; } return Authenticated; }