Esempio n. 1
0
		/// <summary>
		/// 初始化
		/// </summary>
		/// <param name="cfg">初始化使用的配置</param>
		private void Initialize(Config cfg)
		{
			if (_isInitialized) throw new InvalidOperationException("already initialized.");

			System.Diagnostics.Debug.WriteLine("IPMClient 开始初始化...端口:" + cfg.Port.ToString());

			_context = SynchronizationContext.Current;
			SynchronizationContext = SynchronizationContext.Current;

			LocalAddresses = Helper.GetLocalAddresses();

			this.Config = cfg;

			if (cfg.BindedIP == null) cfg.BindedIP = IPAddress.Any;


			//开始构造对象
			Commander = new CommandExecutor(this);
			Commander.Init();

			//初始化插件
			InitializeServiceProvider();

			//初始化调试器
			Debugger = new Debug.DebugHelper();
			Debugger.AttachHelperAuto(this);

			this._isInitialized = Commander.IsInitialized;
		}
		/// <summary>
		/// 加密信息
		/// </summary>
		/// <param name="cmd">Commander</param>
		/// <param name="e">事件参数</param>
		void EncryptMessage(CommandExecutor cmd, Entity.MessageEventArgs e)
		{
			Entity.Host host = null;
			if (cmd.LivedHost == null || (host = cmd.LivedHost.GetHost(e.Message.HostAddr.Address.ToString())) == null || !host.SupportEncrypt) return;

			if (host.PubKey == null)
			{
				//压入队列
				if (host.QueuedMessage == null) host.QueuedMessage = new Queue<FSLib.IPMessager.Entity.Message>();
				host.QueuedMessage.Enqueue(e.Message);
				e.IsHandled = true;

				//请求公钥
				GetPubKey(host);
			}
			else
			{
				if (e.Message.NormalMsgBytes == null)
				{
					System.Text.Encoding enc = e.Message.IsEncodingUnicode ? System.Text.Encoding.Unicode : System.Text.Encoding.Default;
					if (!string.IsNullOrEmpty(e.Message.NormalMsg)) e.Message.NormalMsgBytes = enc.GetBytes(e.Message.NormalMsg);
					else e.Message.NormalMsgBytes = new byte[] { 0 };

					if (!string.IsNullOrEmpty(e.Message.ExtendMessage)) e.Message.ExtendMessageBytes = enc.GetBytes(e.Message.ExtendMessage);
					else e.Message.ExtendMessageBytes = new byte[] { 0 };
				}
				if (e.Message.NormalMsgBytes == null) return;

				//加密
				if (host.IsEncryptUseSmallKey)
				{
					//RSA512&&RC2
					//暂时不支持。。。
					//TODO:加密支持RC2
					e.Message.IsEncrypt = false;
				}
				else
				{
					//RSA1024&BlowFish
					byte[] key = new byte[8];
					rcsp.GetBytes(key);

					blowFish.Initialize(key, 0, key.Length);
					byte[] content = new byte[(int)Math.Ceiling(e.Message.NormalMsgBytes.Length / 16.0) * 16];	//BlowFish加密必须是16字节的整数倍
					e.Message.NormalMsgBytes.CopyTo(content, 0);

					blowFish.Encrypt(content, 0, content, 0, content.Length);
					blowFish.Invalidate();

					//加密Key
					RSAParameters p = new RSAParameters()
					{
						Modulus = host.PubKey,
						Exponent = host.Exponent
					};
					RSA_1024_Encryptor.ImportParameters(p);
					key = RSA_1024_Encryptor.Encrypt(key, false);
					//Array.Reverse(key);

					//组装消息
					System.Text.StringBuilder sb = new StringBuilder();
					sb.Append(EncryptNormalCapa.ToString("x"));
					sb.Append(":");
					sb.Append(key.ConvertToString());
					sb.Append(":");
					sb.Append(content.ConvertToString());

					e.Message.NormalMsg = sb.ToString();
					e.Message.NormalMsgBytes = null;
				}
			}
		}
		/// <summary>
		/// 解析加密信息
		/// </summary>
		/// <param name="cmd">Commander</param>
		/// <param name="e">事件参数</param>
		void DecryptMessage(CommandExecutor cmd, Entity.MessageEventArgs e)
		{
			int index = 0;
			int nextMatch = 0;

			if ((nextMatch = e.Message.NormalMsg.IndexOf(':', index)) == -1) return;
			ulong capa;
			if (!ulong.TryParse(e.Message.NormalMsg.Substring(index, nextMatch - index), System.Globalization.NumberStyles.AllowHexSpecifier, null, out capa)) return;
			//查找密钥
			index = nextMatch + 1;
			if ((nextMatch = e.Message.NormalMsg.IndexOf(':', index)) == -1) return;
			byte[] buf = e.Message.NormalMsg.ConvertToBytes(index, nextMatch);
			//消息加密内容
			byte[] content = e.Message.NormalMsg.ConvertToBytes(nextMatch + 1, e.Message.NormalMsg.Length);

			//解密密钥
			bool isSuccess = false;
			Define.Consts.Cmd_Encrpy_Option encOpt = (Define.Consts.Cmd_Encrpy_Option)capa;
			if ((encOpt & Consts.Cmd_Encrpy_Option.RSA_1024) == Consts.Cmd_Encrpy_Option.RSA_1024)
			{
				//RSA1024
				try
				{
					buf = this.RSA_1024_Decryptor.Decrypt(buf, false);
					isSuccess = true;
				}
				catch (Exception) { }
			}
			else
			{
				try
				{
					buf = this.RSA_512_Decryptor.Decrypt(buf, false);
					isSuccess = true;
				}
				catch (Exception) { }
			}

			if (!isSuccess)
			{
				if ((encOpt & Consts.Cmd_Encrpy_Option.RSA_1024) == Consts.Cmd_Encrpy_Option.RSA_1024)
				{
					cmd.SendCommand(e.Message.HostAddr, Consts.Commands.SendMsg, 0ul, "[AUTO=PUBKEY_EXP]\n\n公钥已经过期,无法解密信息,请刷新主机列表。", "", false, false, true, true, true, false, false, false);
					e.IsHandled = true;	//过滤掉消息
					return;
				}
				else
				{
					cmd.SendCommand(e.Message.HostAddr, Consts.Commands.SendMsg, 0ul, "[AUTO=KEY_NOT_SUPPORT]\n\n您的客户端所使用的加密等级过低,无法支持。", "", false, false, true, true, true, false, false, false);
					e.IsHandled = true;	//过滤掉消息
					return;
				}
			}
			else
			{
				//解密文本
				if ((encOpt & Consts.Cmd_Encrpy_Option.RC2_40) == Consts.Cmd_Encrpy_Option.RC2_40)
				{

					//TODO:RC2加密解决

				}
				else
				{
					//BlowFish
					blowFish.Initialize(buf, 0, buf.Length);
					blowFish.Decrypt(content, 0, content, 0, content.Length);
					blowFish.Invalidate();
				}

				int endIndex = Array.FindIndex(content, (s) => s == 0);
				if (endIndex == -1) endIndex = content.Length;

				if (Define.Consts.Check(e.Message.Options, Define.Consts.Cmd_Send_Option.Content_Unicode))
				{
					e.Message.NormalMsg = System.Text.Encoding.Unicode.GetString(content, 0, endIndex);
				}
				else
				{
					e.Message.NormalMsg = System.Text.Encoding.Default.GetString(content, 0, endIndex);
				}

			}
		}
		/// <summary>
		/// 将信息解密函数挂钩
		/// </summary>
		/// <param name="cmd"></param>
		public void HandleEncryptedMessage(CommandExecutor cmd)
		{
			//加密信息预先解密
			cmd.TextMessageReceiving += (s, e) =>
			{
				if (!e.IsHandled && e.Message.IsEncrypt)
				{
					DecryptMessage(cmd, e);
				}
			};
			cmd.MessageProxy.MessageSending += (s, e) =>
			{
				if (!e.IsHandled && e.Message.Command == Consts.Commands.SendMsg && e.Message.IsEncrypt)
				{
					EncryptMessage(cmd, e);
				}
			};
			cmd.MessageProcessing += (s, e) =>
			{
				if (e.IsHandled || e.Host == null) return;

				if (e.Message.Command == Consts.Commands.AnsPubKey)
				{
					//发送确认消息
					MessageProxy.SendWithNoCheck(e.Host, Consts.Commands.RecvMsg, 0ul, e.Message.PackageNo.ToString(), "");

					//分析
					int index = e.Message.NormalMsg.IndexOf(":");
					if (index == -1) return;

					ulong capa;
					if (!ulong.TryParse(e.Message.NormalMsg.Substring(0, index++), System.Globalization.NumberStyles.AllowHexSpecifier, null, out capa)) return;
					if ((capa & EncryptCapa) == 0) return;

					e.Host.SupportEncrypt = true;
					e.Host.IsEncryptUseSmallKey = (capa & EncryptNormalCapa) == 0;

					int nextMatch;
					if ((nextMatch = e.Message.NormalMsg.IndexOf('-', index)) == -1) return;
					byte[] exp = e.Message.NormalMsg.Substring(index, nextMatch - index).ConvertToBytes();
					if (exp == null) return;

					byte[] pubKey = e.Message.NormalMsg.Substring(nextMatch + 1).ConvertToBytes();
					if (pubKey == null) return;

					e.Host.SetEncryptInfo(pubKey, exp);

					//查看有没有队列消息,有就发出去
					if (e.Host.QueuedMessage != null && e.Host.QueuedMessage.Count > 0)
					{
						Message m = null;
						while (e.Host.QueuedMessage.Count > 0)
						{
							m = e.Host.QueuedMessage.Dequeue();
							MessageProxy.Send(m);
						}
					}
				}
				else if (e.Message.Command == Consts.Commands.GetPubKey)
				{
					ulong capa;
					if (!ulong.TryParse(e.Message.NormalMsg, System.Globalization.NumberStyles.AllowHexSpecifier, null, out capa)) return;

					if ((capa & EncryptCapa) == 0) return;

					//返回响应
					e.Host.SupportEncrypt = true;
					e.Host.IsEncryptUseSmallKey = (capa & EncryptNormalCapa) == 0;

					byte[] key = e.Host.IsEncryptUseSmallKey ? PublicKey_512 : PublicKey_1024;
					byte[] exp = e.Host.IsEncryptUseSmallKey ? Exponent_512 : Exponent_1024;

					string content = string.Format("{0}:{1}-{2}", EncryptCapa.ToString("x"), BitConverter.ToString(exp).Replace("-", ""), BitConverter.ToString(key).Replace("-", "")).ToLower();
					MessageProxy.SendWithNoCheck(e.Host, Consts.Commands.AnsPubKey, 0ul, content, "");
				}
			};

		}