Proxy Library Version 2.0

09/04/2012 16:21 xmen01235#1
This is the major revamp of my old version. Additionally this new library also include the interface of cryptography which is defined in the "connection" class and which is having the signature function of Decrypt and Encrypt. This cryptography interface can be implemented outside the parent class therefore making this proxy library a very flexible tools for creating a proxy with different type of encryption.

Cryptography Interface signature:
Code:
        public interface Icrypto
        {
            void Decrypt(ref byte[] data, bool IsRemServer);
            void Encrypt(ref byte[] data, bool IsRemServer);
        }
We know that we have an interface installed inside the connection class which can implemented on the parent class but we don't know how and when is the right time to initialize it. Well this can be done perfectly during when the proxy established the connection between remote-proxy-client such as the example below.
Code:
        private void myProxy_NewConnectionEvent(object sender, int sessionid)
        {
            //Initialized the encryptor here
            CrypImplementer cryptImp = new CrypImplementer();
            myProxy.SetCryptImp((object)cryptImp, sessionid);

        }

        private class CrypImplementer : connection.Icrypto
        {
            public CrypImplementer() { }

            public void Decrypt(ref byte[] data, bool IsRemServer)
            { 
                /*Define your Decryption here
                 * IrRemServer is true when the data is coming from server 
                 * otherwise it is false
                */
            }
            public void Encrypt(ref byte[] data, bool IsRemServer)
            {
                /*Define your Encryption here
                 * IrRemServer is true when the data is coming from server 
                 * otherwise it is false
                */
            }
 
        }
When the cryptography will be incorporated correctly, a decrypted packet shall be available on the Data arrival events and you can do whatever you want on that packet.
Code:
        private void myProxy_DataArrivalEvent(
            object sender,
            object data,
            int sessionid,
            Boolean IsRemServer)
        {
            connection conn = (connection)sender;
            if (IsRemServer)
            {
                // You can add packet handler here
                conn.SendPC(data);
            }
            else
            {
                // You can add packet handler here
                conn.SendPS(data);
            }
        }
Please take note that I have added the sessionid on each events which also corresponds to the connection id for each remote-proxy-client session. This sessionid is just an incremental value of integer. The purpose of this sessionid is if you want to control the specific connection and if you want to access its public method from the parent class such as the example below.
Code:
connection tmpcon=myProxy.GetConn(sessionid);
tmpcon.SendPC((object) byte); // send data from proxy to client for connection id= sessionid
tmpcon.SendPS((object) byte); // send data from proxy to remote host for  connection id= sessionid

General Implementation of the library:

Importing the library
Code:
using xmenproxy;
Initializing the library.
Code:
/*
* If you have more proxy listening at different port then you can defined different instance for it
*/
ProxyServer myProxy = new ProxyServer();

//ProxyServer myProxy2 = new ProxyServer();
//ProxyServer myProxy3 = new ProxyServer();
//etc
Starting the proxy and defining the events
Code:
            myProxy.RemoteIP = "remotehostip";
            myProxy.RemotePort = 9960;
            myProxy.LocalPort = 9960;
            myProxy.LocalIP = "localhost";
            myProxy.DataArrivalEvent += new ProxyServer.DataArrival(myProxy_DataArrivalEvent);
            myProxy.NewConnectionEvent += new ProxyServer.NewConnection(myProxy_NewConnectionEvent);
            myProxy.StartServer();
Events Callback
Code:
        private void myProxy_NewConnectionEvent(object sender, int sessionid)
        {
            //Initialized the encryptor here
            CrypImplementer cryptImp = new CrypImplementer();
            myProxy.SetCryptImp((object)cryptImp, sessionid);

        }
        private void myProxy_DataArrivalEvent(
            object sender,
            object data,
            int sessionid,
            Boolean IsRemServer)
        {
            connection conn = (connection)sender;
            if (IsRemServer)
            {
                conn.SendPC(data);
            }
            else
            {
                conn.SendPS(data);
            }
        }
See also the attached test proxy example. If you find any bugs please let me know. :D
09/04/2012 18:36 xmen01235#2
Proxy Library Implementation for Authentication Server:

Code:
private ProxyServer AuthSE;
Code:
        private void btnStartServer_Click(object sender, EventArgs e)
        {
            AuthSE = new ProxyServer();
            AuthSE.RemoteIP = "208.96.34.46";            
            AuthSE.RemotePort = 9960;
            AuthSE.LocalPort = 9960;
            AuthSE.LocalIP = myLocalhost.GetmyIP();
            AuthSE.DataArrivalEvent+=new ProxyServer.DataArrival(AuthSE_DataArrivalEvent);
            AuthSE.NewConnectionEvent+=new ProxyServer.NewConnection(AuthSE_NewConnectionEvent);            
            AuthSE.StartServer();
         }
Code:
        private void AuthSE_NewConnectionEvent(object sender, int sessionid)
        { 
            AuthCrypt authcryp=new AuthCrypt();
            AuthSE.SetCryptImp((object)authcryp, sessionid);
        }


        private void AuthSE_DataArrivalEvent(
            object sender,             
            object data,             
            int sessionid,
            Boolean IsRemServer)
        {
            byte[] bytedata = (byte[])data;
            connection conn = (connection)sender;
            if(IsRemServer)
            {
                myPacket SPacket = new myPacket(ref bytedata);
                if (AuthResponce.IsThisType(SPacket))
                {
                    AuthResponce auth = new AuthResponce(ref SPacket);
                    auth.GameServerIp = myLocalhost.GetmyIP();
                }
                conn.SendPC((object)bytedata);
            }
            else
            {
                myPacket CPacket = new myPacket(ref bytedata);
                if (LoginInformation.IsThisType(CPacket))
                {
                    LoginInformation logInfo = new LoginInformation(ref CPacket);
                }

                conn.SendPS((object)bytedata);
            }
        }
Code:
    class AuthCrypt : connection.Icrypto
    {
        private AuthCrypto AutCrypthSP;
        private AuthCrypto AutCrypthCP;

        public AuthCrypt()
        {
            this.AutCrypthSP = new AuthCrypto();
            this.AutCrypthCP = new AuthCrypto();
        }

        public void Decrypt(ref byte[] data, bool IsRemServer)
        {
            if (IsRemServer)
            {
                this.AutCrypthSP.Decrypt(ref data);
            }
            else
            {
                this.AutCrypthCP.Decrypt(ref data);
            }
        }
        public void Encrypt(ref byte[] data, bool IsRemServer)
        {
            if (IsRemServer)
            {
                this.AutCrypthSP.Encrypt(ref data);
            }
            else
            {
                this.AutCrypthCP.Encrypt(ref data);
            }

        }
    }

public class AuthCrypto
    {
        private class crypCounter
        {
            private UInt16 mcounter;
            public crypCounter()
            {
                this.mcounter = 0;
            }
            public byte mkey1()
            {
                return ((byte)(mcounter & 0xFF));
            }
            public byte mkey2()
            {
                return ((byte)(mcounter >> 8));
            }
            public void increment()
            {
                mcounter++;
            }

        }
        private byte[] crypKey1;
        private byte[] crypKey2;
        private crypCounter encryptCounter = new crypCounter();
        private crypCounter decryptCounter = new crypCounter();

        public AuthCrypto()
        {
            crypKey1 = new byte[256];
            crypKey2 = new byte[256];
            byte ikey1 = 0x9D;
            byte ikey2 = 0x62;

            for (int i = 0; i < 256; i++)
            {
                crypKey1[i] = ikey1;
                crypKey2[i] = ikey2;
                ikey1 = (byte)((0x0F + (byte)(ikey1 * 0xFA)) * ikey1 + 0x13);
                ikey2 = (byte)((0x79 - (byte)(ikey2 * 0x5C)) * ikey2 + 0x6D);
            }
        }
        public void Encrypt(ref byte[] buffer)
        {
            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i] ^= (byte)(0xAB);
                buffer[i] = (byte)(buffer[i] >> 4 | buffer[i] << 4);
                buffer[i] ^= (byte)(this.crypKey1[this.encryptCounter.mkey1()] ^ this.crypKey2[this.encryptCounter.mkey2()]);
                this.encryptCounter.increment();
            }

        }
        public void Decrypt(ref byte[] buffer)
        {
            for (int i = 0; i < buffer.Length; i++)
            {
                buffer[i] ^= (byte)(this.crypKey2[this.decryptCounter.mkey2()] ^ this.crypKey1[this.decryptCounter.mkey1()]);
                buffer[i] = (byte)(buffer[i] >> 4 | buffer[i] << 4);
                buffer[i] ^= (byte)(0xAB);
                this.decryptCounter.increment();
            }
        }
    }
For Game server, you can follow the same but you need to change the encryption type and you need to add the DH handshaking.
09/04/2012 19:10 KraHen#3
I like the idea, but I really don`t like your API design. I`m used to creating APIs for my personal projects as well, but I tend to use waaaay more abstraction.

Nevertheless, I`m sure there are people who can and are willing to use this, and it truly is a good contribution. I salute you. :)
09/04/2012 19:38 xmen01235#4
Quote:
Originally Posted by KraHen View Post
I like the idea, but I really don`t like your API design. I`m used to creating APIs for my personal projects as well, but I tend to use waaaay more abstraction.

Nevertheless, I`m sure there are people who can and are willing to use this, and it truly is a good contribution. I salute you. :)
I tend to program on VB style but I am getting so addicted with c# :)... Honestly I am not a programmer in profession and this is just my hobby but I learned a lot from you guys. But I studied a lot the style of coding from each programmer and tend to follow on their style if I like it. I know you will laugh at me but I still don't have any idea what really abstraction is lol. But I am going to research on that until I will get a full grasp on that matter and going to implement on my program.

Thanks for cheering me up :D...
09/04/2012 21:56 I don't have a username#5
Great to see this, quite a few proxy stuff coming out lately as well other stuff :) It's just amazing :)
09/06/2012 02:31 JohnHeatz#6
I really like this one, maybe due to me being using VB.Net as well for quite some time now, yet I am getting into C# step by step, hope to see some more about this soon, and be able to develop my own soon too.