MessageRouterClient.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. using System;
  2. using System.Net;
  3. using System.Text;
  4. using System.Timers;
  5. using System.Collections.Specialized;
  6. namespace MessageRouter
  7. {
  8. public delegate void OnMessageRouterMessageReceivedDelegate(MessageRouterClient client,
  9. string messageType,
  10. string eventType,
  11. StringDictionary parameters);
  12. public class MessageRouterClient : MessageRouterConnection
  13. {
  14. private const char CRYPT_FORMAT_NONE = '5'; // 5
  15. private const char MESSAGE_VERSION = '2'; // 2
  16. public OnMessageRouterMessageReceivedDelegate OnMessageRouterMessageReceived;
  17. private char cryptFormat;
  18. private char messageVersion;
  19. private Timer echoTimer;
  20. public MessageRouterClient(IPEndPoint serverEndPoint)
  21. : this(serverEndPoint, CRYPT_FORMAT_NONE, MESSAGE_VERSION)
  22. {
  23. }
  24. public MessageRouterClient(IPEndPoint serverEndPoint, char cryptFormat, char messageVersion)
  25. : base(serverEndPoint)
  26. {
  27. this.cryptFormat = cryptFormat;
  28. this.messageVersion = messageVersion; // NOTE: Message Version only exists if Crypt Format > 5
  29. Init();
  30. }
  31. private void Init()
  32. {
  33. OnPacketReceived += new OnMessageRouterPacketReceivedDelegate(MessageRouterPacketReceived);
  34. echoTimer = new Timer(150 * 1000); // 150 secs
  35. echoTimer.Elapsed += new ElapsedEventHandler(EchoTimerElapsed);
  36. echoTimer.Enabled = true;
  37. }
  38. void EchoTimerElapsed(object sender, ElapsedEventArgs e)
  39. {
  40. this.SendEcho();
  41. }
  42. protected void MessageRouterPacketReceived(MessageRouterConnection client, MessageRouterPacket p)
  43. {
  44. // Parse message router packet and retrieve
  45. // 1. Message Type
  46. // 2. Event Type
  47. // 3. Parameters
  48. ASCIIEncoding enc = new ASCIIEncoding();
  49. string data = enc.GetString(p.buf);
  50. if (cryptFormat != '5')
  51. {
  52. byte[] bytes = new byte[p.buf.Length - 1];
  53. Buffer.BlockCopy(p.buf, 0, bytes, 0, p.buf.Length - 1); // trim '^'
  54. string szKey = string.Format("{0:d5}|{1:c}|{2:d6}", p.buf.Length, cryptFormat, LocalPort);
  55. byte[] ba = SSFCrypt(bytes, szKey);
  56. data = enc.GetString(ba);
  57. }
  58. //Console.WriteLine("READ DATA: " + data);
  59. string[] entries = data.Split(new Char[] { '|' });
  60. // Message Version (0)
  61. // User ID (1)
  62. // Message Type (2)
  63. // Event Type (3)
  64. // Destination (4)
  65. // Origin (5)
  66. // Parameters in name=value format
  67. // ^
  68. if (entries.Length < 8)
  69. {
  70. // TODO: Handle malformed message dta
  71. }
  72. string msgType = entries[2];
  73. string evtType = entries[3];
  74. StringDictionary sd = new StringDictionary();
  75. for (int i = 6; i < entries.Length - 1; i++)
  76. {
  77. string param = entries[i];
  78. // find the first index of '='
  79. int pos = param.IndexOf('=');
  80. if (pos == -1)
  81. continue;
  82. string key = param.Substring(0, pos);
  83. string val = param.Substring(pos + 1);
  84. if (key == null || key.Length == 0)
  85. continue;
  86. sd.Add(key, val);
  87. }
  88. if (OnMessageRouterMessageReceived != null)
  89. OnMessageRouterMessageReceived(this, msgType, evtType, sd);
  90. }
  91. private bool SendEcho()
  92. {
  93. String msg = this.messageVersion + "||ECHO|||||^";
  94. return SendMessage(msg);
  95. }
  96. public bool SendMessage(string msg)
  97. {
  98. //Console.WriteLine("WRITE LEN: {0}", msg.Length + 1);
  99. //Console.WriteLine("WRITE CRYPT: {0}", cryptFormat);
  100. //Console.WriteLine("WRITE DATA: {0}", msg);
  101. string msgx;
  102. if (cryptFormat != '5')
  103. {
  104. msg = msg.TrimEnd('^');
  105. string szKey = string.Format("{0:d5}|{1:c}|{2:d6}", msg.Length + 1, cryptFormat, LocalPort);
  106. return Write(cryptFormat, SSFCrypt(msg, szKey));
  107. }
  108. msgx = msg;
  109. ASCIIEncoding encoding = new ASCIIEncoding();
  110. return Write(cryptFormat, encoding.GetBytes(msgx));
  111. }
  112. private byte[] SSFCrypt(string data, string key)
  113. {
  114. ASCIIEncoding enc = new ASCIIEncoding();
  115. byte[] ba = enc.GetBytes(data);
  116. return SSFCrypt(ba, key);
  117. }
  118. private byte[] SSFCrypt(byte[] data, string key)
  119. {
  120. //we will consider size of sbox 256 bytes
  121. //(extra byte are only to prevent any mishep just in case)
  122. sbyte[] Sbox = new sbyte[257];
  123. sbyte[] Sbox2 = new sbyte[257];
  124. UInt32 i, j, t;
  125. sbyte temp, k;
  126. i = j = t = 0;
  127. temp = k = (sbyte)0x00;
  128. //always initialize the arrays with zero
  129. for (i = 0; i < 257; i++)
  130. {
  131. Sbox[i] = Sbox2[i] = (sbyte)0x00;
  132. }
  133. //initialize sbox i
  134. for (i = 0; i < 256; i++)
  135. {
  136. Sbox[i] = (sbyte)i;
  137. }
  138. j = 0;
  139. //initialize the sbox2 with user key
  140. for (i = 0; i < 256; i++)
  141. {
  142. if (j == Convert.ToUInt32(key.Length))
  143. {
  144. j = 0;
  145. }
  146. Sbox2[i] = (sbyte)key[Convert.ToInt32(j++)];
  147. }
  148. j = 0; //Initialize j
  149. //scramble sbox1 with sbox2
  150. for (i = 0; i < 256; i++)
  151. {
  152. j = (j + (UInt32)Sbox[i] + (UInt32)Sbox2[i]) % 256;
  153. temp = Sbox[i];
  154. Sbox[i] = Sbox[j];
  155. Sbox[j] = temp;
  156. }
  157. i = j = 0;
  158. sbyte[] res = new sbyte[data.Length];
  159. for (int x = 0; x < data.Length; x++)
  160. {
  161. //increment i
  162. i = (i + 1) % 256;
  163. //increment j
  164. j = (j + (UInt32)Sbox[i]) % 256;
  165. //Scramble SBox #1 further so encryption routine will
  166. //will repeat itself at great interval
  167. temp = Sbox[i];
  168. Sbox[i] = Sbox[j];
  169. Sbox[j] = temp;
  170. //Get ready to create pseudo random byte for encryption key
  171. t = ((UInt32)Sbox[i] + (UInt32)Sbox[j]) % 256;
  172. //get the random byte
  173. k = Sbox[t];
  174. //xor with the data and done
  175. res[x] = (sbyte)(data[x] ^ k);
  176. }
  177. byte[] bytes = new byte[res.Length + 1];
  178. Buffer.BlockCopy(res, 0, bytes, 0, res.Length);
  179. bytes[res.Length] = 0x5E; // '^'
  180. return bytes;
  181. }
  182. }
  183. }