123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- using System;
- using System.Net;
- using System.Text;
- using System.Timers;
- using System.Collections.Specialized;
- namespace MessageRouter
- {
- public delegate void OnMessageRouterMessageReceivedDelegate(MessageRouterClient client,
- string messageType,
- string eventType,
- StringDictionary parameters);
- public class MessageRouterClient : MessageRouterConnection
- {
- private const char CRYPT_FORMAT_NONE = '5'; // 5
- private const char MESSAGE_VERSION = '2'; // 2
- public OnMessageRouterMessageReceivedDelegate OnMessageRouterMessageReceived;
- private char cryptFormat;
- private char messageVersion;
- private Timer echoTimer;
- public MessageRouterClient(IPEndPoint serverEndPoint)
- : this(serverEndPoint, CRYPT_FORMAT_NONE, MESSAGE_VERSION)
- {
- }
- public MessageRouterClient(IPEndPoint serverEndPoint, char cryptFormat, char messageVersion)
- : base(serverEndPoint)
- {
- this.cryptFormat = cryptFormat;
- this.messageVersion = messageVersion; // NOTE: Message Version only exists if Crypt Format > 5
- Init();
- }
- private void Init()
- {
- OnPacketReceived += new OnMessageRouterPacketReceivedDelegate(MessageRouterPacketReceived);
- echoTimer = new Timer(150 * 1000); // 150 secs
- echoTimer.Elapsed += new ElapsedEventHandler(EchoTimerElapsed);
- echoTimer.Enabled = true;
- }
- void EchoTimerElapsed(object sender, ElapsedEventArgs e)
- {
- this.SendEcho();
- }
- protected void MessageRouterPacketReceived(MessageRouterConnection client, MessageRouterPacket p)
- {
- // Parse message router packet and retrieve
- // 1. Message Type
- // 2. Event Type
- // 3. Parameters
- ASCIIEncoding enc = new ASCIIEncoding();
- string data = enc.GetString(p.buf);
- if (cryptFormat != '5')
- {
- byte[] bytes = new byte[p.buf.Length - 1];
- Buffer.BlockCopy(p.buf, 0, bytes, 0, p.buf.Length - 1); // trim '^'
- string szKey = string.Format("{0:d5}|{1:c}|{2:d6}", p.buf.Length, cryptFormat, LocalPort);
- byte[] ba = SSFCrypt(bytes, szKey);
- data = enc.GetString(ba);
- }
- //Console.WriteLine("READ DATA: " + data);
- string[] entries = data.Split(new Char[] { '|' });
- // Message Version (0)
- // User ID (1)
- // Message Type (2)
- // Event Type (3)
- // Destination (4)
- // Origin (5)
- // Parameters in name=value format
- // ^
- if (entries.Length < 8)
- {
- // TODO: Handle malformed message dta
- }
- string msgType = entries[2];
- string evtType = entries[3];
- StringDictionary sd = new StringDictionary();
- for (int i = 6; i < entries.Length - 1; i++)
- {
- string param = entries[i];
- // find the first index of '='
- int pos = param.IndexOf('=');
- if (pos == -1)
- continue;
- string key = param.Substring(0, pos);
- string val = param.Substring(pos + 1);
- if (key == null || key.Length == 0)
- continue;
- sd.Add(key, val);
- }
- if (OnMessageRouterMessageReceived != null)
- OnMessageRouterMessageReceived(this, msgType, evtType, sd);
- }
- private bool SendEcho()
- {
- String msg = this.messageVersion + "||ECHO|||||^";
- return SendMessage(msg);
- }
- public bool SendMessage(string msg)
- {
- //Console.WriteLine("WRITE LEN: {0}", msg.Length + 1);
- //Console.WriteLine("WRITE CRYPT: {0}", cryptFormat);
- //Console.WriteLine("WRITE DATA: {0}", msg);
- string msgx;
- if (cryptFormat != '5')
- {
- msg = msg.TrimEnd('^');
- string szKey = string.Format("{0:d5}|{1:c}|{2:d6}", msg.Length + 1, cryptFormat, LocalPort);
- return Write(cryptFormat, SSFCrypt(msg, szKey));
- }
- msgx = msg;
- ASCIIEncoding encoding = new ASCIIEncoding();
- return Write(cryptFormat, encoding.GetBytes(msgx));
- }
- private byte[] SSFCrypt(string data, string key)
- {
- ASCIIEncoding enc = new ASCIIEncoding();
- byte[] ba = enc.GetBytes(data);
- return SSFCrypt(ba, key);
- }
- private byte[] SSFCrypt(byte[] data, string key)
- {
- //we will consider size of sbox 256 bytes
- //(extra byte are only to prevent any mishep just in case)
- sbyte[] Sbox = new sbyte[257];
- sbyte[] Sbox2 = new sbyte[257];
- UInt32 i, j, t;
- sbyte temp, k;
- i = j = t = 0;
- temp = k = (sbyte)0x00;
- //always initialize the arrays with zero
- for (i = 0; i < 257; i++)
- {
- Sbox[i] = Sbox2[i] = (sbyte)0x00;
- }
- //initialize sbox i
- for (i = 0; i < 256; i++)
- {
- Sbox[i] = (sbyte)i;
- }
- j = 0;
- //initialize the sbox2 with user key
- for (i = 0; i < 256; i++)
- {
- if (j == Convert.ToUInt32(key.Length))
- {
- j = 0;
- }
- Sbox2[i] = (sbyte)key[Convert.ToInt32(j++)];
- }
- j = 0; //Initialize j
- //scramble sbox1 with sbox2
- for (i = 0; i < 256; i++)
- {
- j = (j + (UInt32)Sbox[i] + (UInt32)Sbox2[i]) % 256;
- temp = Sbox[i];
- Sbox[i] = Sbox[j];
- Sbox[j] = temp;
- }
- i = j = 0;
- sbyte[] res = new sbyte[data.Length];
- for (int x = 0; x < data.Length; x++)
- {
- //increment i
- i = (i + 1) % 256;
- //increment j
- j = (j + (UInt32)Sbox[i]) % 256;
- //Scramble SBox #1 further so encryption routine will
- //will repeat itself at great interval
- temp = Sbox[i];
- Sbox[i] = Sbox[j];
- Sbox[j] = temp;
- //Get ready to create pseudo random byte for encryption key
- t = ((UInt32)Sbox[i] + (UInt32)Sbox[j]) % 256;
- //get the random byte
- k = Sbox[t];
- //xor with the data and done
- res[x] = (sbyte)(data[x] ^ k);
- }
- byte[] bytes = new byte[res.Length + 1];
- Buffer.BlockCopy(res, 0, bytes, 0, res.Length);
- bytes[res.Length] = 0x5E; // '^'
- return bytes;
- }
- }
- }
|