private void InitializeProxySendCallback(IAsyncResult ar) { if (!Disposed) { BaseSocketConnection connection = null; MessageBuffer writeMessage = null; CallbackData callbackData = null; try { callbackData = (CallbackData)ar.AsyncState; connection = callbackData.Connection; writeMessage = callbackData.Buffer; if (connection.Active) { //----- Socket! int writeBytes = connection.Socket.EndSend(ar); if (writeBytes < writeMessage.PacketRemaining) { //----- Continue to send until all bytes are sent! writeMessage.PacketOffSet += writeBytes; connection.Socket.BeginSend(writeMessage.PacketBuffer, writeMessage.PacketOffSet, writeMessage.PacketRemaining, SocketFlags.None, new AsyncCallback(InitializeProxySendCallback), callbackData); } else { writeMessage = null; callbackData = null; MessageBuffer readMessage = new MessageBuffer(4096); connection.Socket.BeginReceive(readMessage.PacketBuffer, readMessage.PacketOffSet, readMessage.PacketRemaining, SocketFlags.None, new AsyncCallback(InitializeProxyReceiveCallback), new CallbackData(connection, readMessage)); } } } catch (Exception ex) { Host.FireOnException(connection, ex); } } }
/// <summary> /// Receive data from connetion. /// </summary> internal void BeginReceive(BaseSocketConnection connection) { if (!Disposed) { try { if (connection.Active) { lock (connection.SyncReadCount) { if (connection.ReadCanEnqueue) { if (connection.ReadCount == 0) { //----- if the connection is not receiving, start the receive! MessageBuffer readMessage = new MessageBuffer(FSocketBufferSize); if (connection.Stream != null) { //----- Ssl! connection.Stream.BeginRead(readMessage.PacketBuffer, readMessage.PacketOffSet, readMessage.PacketRemaining, new AsyncCallback(BeginReadCallback), new CallbackData(connection, readMessage)); } else { //----- Socket! connection.Socket.BeginReceive(readMessage.PacketBuffer, readMessage.PacketOffSet, readMessage.PacketRemaining, SocketFlags.None, new AsyncCallback(BeginReadCallback), new CallbackData(connection, readMessage)); } } //----- Increase the read count! connection.ReadCount++; } } } } catch (Exception ex) { FireOnException(connection, ex); } } }
private byte[] ReadMessageWithMessageTail(byte[] connectionDelimiter, CallbackData callbackData, ref bool socketWasRead) { string stringDelimiter = Encoding.GetEncoding(1252).GetString(connectionDelimiter); byte[] rawBuffer = null; BaseSocketConnection connection = callbackData.Connection; MessageBuffer readMessage = callbackData.Buffer; //----- Message with delimiter! int delimiterSize = connectionDelimiter.Length; bool readPacket = false; bool readSocket = false; do { rawBuffer = null; if (readMessage.PacketOffSet > delimiterSize) { int index = Encoding.GetEncoding(1252).GetString(readMessage.PacketBuffer).IndexOf(stringDelimiter); if (index >= 0) { rawBuffer = readMessage.GetRawBufferWithTail(connection, index, delimiterSize); //----- Decrypt! rawBuffer = CryptUtils.DecryptData(connection, rawBuffer, FMessageBufferSize); if (readMessage.PacketOffSet == 0) { readPacket = false; readSocket = false; } else { readPacket = true; readSocket = false; FireOnReceived(connection, rawBuffer, false); } } else { readPacket = false; readSocket = true; } } else { readPacket = false; readSocket = (readMessage.PacketOffSet > 0); } } while (readPacket); //----- Adjust room for more! readMessage.Resize(FMessageBufferSize); if (readSocket) { if (connection.Active) { //----- Read More! if (connection.Stream != null) { //----- Ssl! connection.Stream.BeginRead(readMessage.PacketBuffer, readMessage.PacketOffSet, readMessage.PacketRemaining, new AsyncCallback(BeginReadCallback), callbackData); } else { //----- Socket! connection.Socket.BeginReceive(readMessage.PacketBuffer, readMessage.PacketOffSet, readMessage.PacketRemaining, SocketFlags.None, new AsyncCallback(BeginReadCallback), callbackData); } } } socketWasRead = readSocket; return(rawBuffer); }
private byte[] ReadMessageWithPacketHeader(byte[] connectionDelimiter, CallbackData callbackData, ref bool socketWasRead) { byte[] rawBuffer = null; BaseSocketConnection connection = callbackData.Connection; MessageBuffer readMessage = callbackData.Buffer; //----- Message with delimiter! int delimiterSize = connectionDelimiter.Length + 3; bool readPacket = false; bool readSocket = false; do { rawBuffer = null; if (readMessage.PacketOffSet > delimiterSize) { //----- Has Delimiter! for (int i = 0; i < connectionDelimiter.Length; i++) { if (connectionDelimiter[i] != readMessage.PacketBuffer[i]) { //----- Bad Delimiter! throw new BadDelimiterException("Message delimiter is different from Host delimiter."); } } //----- Get Length! int messageLength = (readMessage.PacketBuffer[connectionDelimiter.Length] << 16) + (readMessage.PacketBuffer[connectionDelimiter.Length + 1] << 8) + (readMessage.PacketBuffer[connectionDelimiter.Length + 2]); if (messageLength > FMessageBufferSize) { throw new MessageLengthException("Message length is greater than Host maximum message length."); } //----- Check Length! if (messageLength == readMessage.PacketOffSet) { //----- Equal -> Get rawBuffer! rawBuffer = readMessage.GetRawBuffer(messageLength, delimiterSize); //----- Decrypt! rawBuffer = CryptUtils.DecryptData(connection, rawBuffer, FMessageBufferSize); readPacket = false; readSocket = false; } else { if (messageLength < readMessage.PacketOffSet) { //----- Less -> Get rawBuffer and fire event! rawBuffer = readMessage.GetRawBuffer(messageLength, delimiterSize); //----- Decrypt! rawBuffer = CryptUtils.DecryptData(connection, rawBuffer, FMessageBufferSize); readPacket = true; readSocket = false; FireOnReceived(connection, rawBuffer, false); } else { if (messageLength > readMessage.PacketOffSet) { //----- Greater -> Read Socket! if (messageLength > readMessage.PacketLength) { readMessage.Resize(messageLength); } readPacket = false; readSocket = true; } } } } else { if (readMessage.PacketRemaining < delimiterSize) { //----- Adjust room for more! readMessage.Resize(readMessage.PacketLength + delimiterSize); } readPacket = false; readSocket = true; } } while (readPacket); if (readSocket) { if (connection.Active) { //----- Read More! if (connection.Stream != null) { //----- Ssl! connection.Stream.BeginRead(readMessage.PacketBuffer, readMessage.PacketOffSet, readMessage.PacketRemaining, new AsyncCallback(BeginReadCallback), callbackData); } else { //----- Socket! connection.Socket.BeginReceive(readMessage.PacketBuffer, readMessage.PacketOffSet, readMessage.PacketRemaining, SocketFlags.None, new AsyncCallback(BeginReadCallback), callbackData); } } } socketWasRead = readSocket; return(rawBuffer); }
private void ReadBytesFromConnection(CallbackData callbackData, int readBytes) { BaseSocketConnection connection = callbackData.Connection; MessageBuffer readMessage = callbackData.Buffer; //----- Has bytes! connection.LastAction = DateTime.Now; byte[] rawBuffer = null; bool socketWasRead = false; readMessage.PacketOffSet += readBytes; switch (connection.DelimiterType) { case DelimiterType.dtNone: //----- Message with no delimiter! rawBuffer = readMessage.GetRawBuffer(readBytes, 0); break; case DelimiterType.dtPacketHeader: //----- Message with packet header! rawBuffer = ReadMessageWithPacketHeader(connection.Delimiter, callbackData, ref socketWasRead); break; case DelimiterType.dtMessageTailExcludeOnReceive: case DelimiterType.dtMessageTailIncludeOnReceive: //----- Message with tail! rawBuffer = ReadMessageWithMessageTail(connection.Delimiter, callbackData, ref socketWasRead); break; } if (rawBuffer != null) { //----- Decrypt! //rawBuffer = CryptUtils.DecryptData(connection, rawBuffer, FMessageBufferSize); //----- Fire Event! FireOnReceived(connection, rawBuffer, true); } readMessage = null; callbackData = null; if (!socketWasRead) { //----- Check Queue! lock (connection.SyncReadCount) { connection.ReadCount--; if (connection.ReadCount > 0) { //----- if it need more receiving, start the receive! MessageBuffer continueReadMessage = new MessageBuffer(FSocketBufferSize); //----- if the read queue has items, start to receive! if (connection.Stream != null) { //----- Ssl! connection.Stream.BeginRead(continueReadMessage.PacketBuffer, continueReadMessage.PacketOffSet, continueReadMessage.PacketRemaining, new AsyncCallback(BeginReadCallback), new CallbackData(connection, continueReadMessage)); } else { //----- Socket! connection.Socket.BeginReceive(continueReadMessage.PacketBuffer, continueReadMessage.PacketOffSet, continueReadMessage.PacketRemaining, SocketFlags.None, new AsyncCallback(BeginReadCallback), new CallbackData(connection, continueReadMessage)); } } } } }
/// <summary> /// Send Callback Processing. /// </summary> private void BeginSendCallbackProcessing(object state) { if (!Disposed) { IAsyncResult ar = (IAsyncResult)state; BaseSocketConnection connection = null; MessageBuffer writeMessage = null; bool CanReadQueue = false; try { CallbackData callbackData = (CallbackData)ar.AsyncState; writeMessage = callbackData.Buffer; connection = callbackData.Connection; if (connection.Active) { if (connection.Stream != null) { //----- Ssl! connection.Stream.EndWrite(ar); FireOnSent(connection, writeMessage.RawBuffer, writeMessage.SentByServer); CanReadQueue = true; } else { //----- Socket! int writeBytes = connection.Socket.EndSend(ar); if (writeBytes < writeMessage.PacketRemaining) { //----- Continue to send until all bytes are sent! writeMessage.PacketOffSet += writeBytes; connection.Socket.BeginSend(writeMessage.PacketBuffer, writeMessage.PacketOffSet, writeMessage.PacketRemaining, SocketFlags.None, new AsyncCallback(BeginSendCallback), callbackData); } else { FireOnSent(connection, writeMessage.RawBuffer, writeMessage.SentByServer); CanReadQueue = true; } } //----- Check Queue! if (CanReadQueue) { callbackData = null; writeMessage = null; lock (connection.WriteQueue) { if (connection.WriteQueue.Count > 0) { //----- If has items, send it! MessageBuffer dequeueWriteMessage = connection.WriteQueue.Dequeue(); if (connection.Stream != null) { //----- Ssl! connection.Stream.BeginWrite(dequeueWriteMessage.PacketBuffer, dequeueWriteMessage.PacketOffSet, dequeueWriteMessage.PacketRemaining, new AsyncCallback(BeginSendCallback), new CallbackData(connection, dequeueWriteMessage)); } else { //----- Socket! connection.Socket.BeginSend(dequeueWriteMessage.PacketBuffer, dequeueWriteMessage.PacketOffSet, dequeueWriteMessage.PacketRemaining, SocketFlags.None, new AsyncCallback(BeginSendCallback), new CallbackData(connection, dequeueWriteMessage)); } } else { connection.WriteQueueHasItems = false; } } } } } catch (Exception ex) { FireOnException(connection, ex); } } }
/// <summary> /// Gets a packet message! /// </summary> /// <param name="connection"> /// Socket connection. /// </param> /// <param name="buffer"> /// Data. /// </param> public static MessageBuffer GetPacketMessage(BaseSocketConnection connection, byte[] buffer) { byte[] workBuffer = null; MessageBuffer messageBuffer = null; workBuffer = CryptUtils.EncryptData(connection, buffer); switch (connection.DelimiterType) { case DelimiterType.dtNone: //----- No Delimiter! messageBuffer = new MessageBuffer(buffer, workBuffer); break; case DelimiterType.dtPacketHeader: if (connection.Delimiter != null && connection.Delimiter.Length >= 0) { //----- Need delimiter! int delimiterSize = connection.Delimiter.Length + 3; byte[] result = new byte[workBuffer.Length + delimiterSize]; int messageLength = result.Length; //----- Delimiter! for (int i = 0; i < connection.Delimiter.Length; i++) { result[i] = connection.Delimiter[i]; } //----- Length! result[connection.Delimiter.Length] = Convert.ToByte((messageLength & 0xFF0000) >> 16); result[connection.Delimiter.Length + 1] = Convert.ToByte((messageLength & 0xFF00) >> 8); result[connection.Delimiter.Length + 2] = Convert.ToByte(messageLength & 0xFF); Buffer.BlockCopy(workBuffer, 0, result, delimiterSize, workBuffer.Length); messageBuffer = new MessageBuffer(buffer, result); } break; case DelimiterType.dtMessageTailExcludeOnReceive: case DelimiterType.dtMessageTailIncludeOnReceive: if (connection.Delimiter != null && connection.Delimiter.Length >= 0) { //----- Need delimiter! byte[] result = new byte[workBuffer.Length + connection.Delimiter.Length]; Buffer.BlockCopy(workBuffer, 0, result, 0, workBuffer.Length); Buffer.BlockCopy(connection.Delimiter, 0, result, workBuffer.Length, connection.Delimiter.Length); messageBuffer = new MessageBuffer(buffer, result); } break; } return(messageBuffer); }
public CallbackData(BaseSocketConnection connection, MessageBuffer buffer) { FConnection = connection; FBuffer = buffer; }
private void InitializeConnectionReceiveCallback(IAsyncResult ar) { if (!Disposed) { BaseSocketConnection connection = null; MessageBuffer readMessage = null; try { CallbackData callbackData = (CallbackData)ar.AsyncState; connection = callbackData.Connection; readMessage = callbackData.Buffer; if (connection.Active) { bool readSocket = true; bool completed = false; int readBytes = connection.Socket.EndReceive(ar); if (readBytes > 0) { readMessage.PacketOffSet += readBytes; byte[] message = null; try { message = Convert.FromBase64String(Encoding.GetEncoding(1252).GetString(readMessage.PacketBuffer, 0, readMessage.PacketOffSet)); } catch (FormatException) { //----- Base64 transformation error! } if ((message != null) && (Encoding.GetEncoding(1252).GetString(message).Contains("</AuthMessage>"))) { //----- Get RSA provider! RSACryptoServiceProvider serverPrivateKey; RSACryptoServiceProvider clientPublicKey = new RSACryptoServiceProvider(); byte[] signMessage; FCryptoService.OnSymmetricAuthenticate(connection, out serverPrivateKey, out signMessage); //----- Deserialize authentication message! MemoryStream m = new MemoryStream(); m.Write(message, 0, message.Length); m.Position = 0; XmlSerializer xml = new XmlSerializer(typeof(AuthMessage)); AuthMessage am = (AuthMessage)xml.Deserialize(m); //----- Generates symmetric algoritm! SymmetricAlgorithm sa = CryptUtils.CreateSymmetricAlgoritm(connection.EncryptType); sa.Key = serverPrivateKey.Decrypt(am.SessionKey, false); sa.IV = serverPrivateKey.Decrypt(am.SessionIV, false); //----- Adjust connection cryptors! connection.Encryptor = sa.CreateEncryptor(); connection.Decryptor = sa.CreateDecryptor(); //----- Verify sign! clientPublicKey.FromXmlString(Encoding.UTF8.GetString(CryptUtils.DecryptDataForAuthenticate(sa, am.SourceKey, PaddingMode.ISO10126))); m.SetLength(0); m.Write(am.SourceKey, 0, am.SourceKey.Length); m.Write(am.SessionKey, 0, am.SessionKey.Length); m.Write(signMessage, 0, signMessage.Length); if (clientPublicKey.VerifyData(CryptUtils.EncryptDataForAuthenticate(sa, m.ToArray(), PaddingMode.PKCS7), new SHA1CryptoServiceProvider(), am.Sign)) { completed = true; } readSocket = false; m.Close(); am.SessionIV.Initialize(); am.SessionKey.Initialize(); serverPrivateKey.Clear(); clientPublicKey.Clear(); readMessage = null; callbackData = null; if (!completed) { throw new SymmetricAuthenticationException("Symmetric sign error."); } FHost.FireOnConnected(connection); } if (readSocket) { connection.Socket.BeginReceive(readMessage.PacketBuffer, readMessage.PacketOffSet, readMessage.PacketRemaining, SocketFlags.None, new AsyncCallback(InitializeConnectionReceiveCallback), callbackData); } } else { throw new SymmetricAuthenticationException("Symmetric authentication error."); } } } catch (Exception ex) { FHost.FireOnException(connection, ex); } } }
protected void InitializeCryptService(BaseSocketConnection connection) { //----- None! if (connection.EncryptType == EncryptType.etNone || connection.EncryptType == EncryptType.etBase64) { FHost.FireOnConnected(connection); } //----- Symmetric! if (connection.EncryptType == EncryptType.etRijndael || connection.EncryptType == EncryptType.etTripleDES) { if (FHost.HostType == HostType.htClient) { //----- Get RSA provider! RSACryptoServiceProvider serverPublicKey; RSACryptoServiceProvider clientPrivateKey = new RSACryptoServiceProvider(); byte[] signMessage; FCryptoService.OnSymmetricAuthenticate(connection, out serverPublicKey, out signMessage); //----- Generates symmetric algoritm! SymmetricAlgorithm sa = CryptUtils.CreateSymmetricAlgoritm(connection.EncryptType); sa.GenerateIV(); sa.GenerateKey(); //----- Adjust connection cryptors! connection.Encryptor = sa.CreateEncryptor(); connection.Decryptor = sa.CreateDecryptor(); //----- Create authenticate structure! AuthMessage am = new AuthMessage(); am.SessionIV = serverPublicKey.Encrypt(sa.IV, false); am.SessionKey = serverPublicKey.Encrypt(sa.Key, false); am.SourceKey = CryptUtils.EncryptDataForAuthenticate(sa, Encoding.UTF8.GetBytes(clientPrivateKey.ToXmlString(false)), PaddingMode.ISO10126); //----- Sign message with am.SourceKey, am.SessionKey and signMessage! //----- Need to use PaddingMode.PKCS7 in sign! MemoryStream m = new MemoryStream(); m.Write(am.SourceKey, 0, am.SourceKey.Length); m.Write(am.SessionKey, 0, am.SessionKey.Length); m.Write(signMessage, 0, signMessage.Length); am.Sign = clientPrivateKey.SignData(CryptUtils.EncryptDataForAuthenticate(sa, m.ToArray(), PaddingMode.PKCS7), new SHA1CryptoServiceProvider()); //----- Serialize authentication message! XmlSerializer xml = new XmlSerializer(typeof(AuthMessage)); m.SetLength(0); xml.Serialize(m, am); //----- Send structure! MessageBuffer mb = new MessageBuffer(0); mb.PacketBuffer = Encoding.GetEncoding(1252).GetBytes(Convert.ToBase64String(m.ToArray())); connection.Socket.BeginSend(mb.PacketBuffer, mb.PacketOffSet, mb.PacketRemaining, SocketFlags.None, new AsyncCallback(InitializeConnectionSendCallback), new CallbackData(connection, mb)); m.Close(); am.SessionIV.Initialize(); am.SessionKey.Initialize(); serverPublicKey.Clear(); clientPrivateKey.Clear(); } else { //----- Create empty authenticate structure! MessageBuffer mb = new MessageBuffer(8192); //----- Start receive structure! connection.Socket.BeginReceive(mb.PacketBuffer, mb.PacketOffSet, mb.PacketRemaining, SocketFlags.None, new AsyncCallback(InitializeConnectionReceiveCallback), new CallbackData(connection, mb)); } } //----- Asymmetric! if (connection.EncryptType == EncryptType.etSSL) { if (FHost.HostType == HostType.htClient) { //----- Get SSL items! X509Certificate2Collection certs = null; string serverName = null; bool checkRevocation = true; FCryptoService.OnSSLClientAuthenticate(connection, out serverName, ref certs, ref checkRevocation); //----- Authneticate SSL! SslStream ssl = new SslStream(new NetworkStream(connection.Socket), true, new RemoteCertificateValidationCallback(ValidateServerCertificateCallback)); if (certs == null) { ssl.BeginAuthenticateAsClient(serverName, new AsyncCallback(SslAuthenticateCallback), new AuthenticateCallbackData(connection, ssl, HostType.htClient)); } else { ssl.BeginAuthenticateAsClient(serverName, certs, System.Security.Authentication.SslProtocols.Default, checkRevocation, new AsyncCallback(SslAuthenticateCallback), new AuthenticateCallbackData(connection, ssl, HostType.htClient)); } } else { //----- Get SSL items! X509Certificate2 cert = null; bool clientAuthenticate = false; bool checkRevocation = true; FCryptoService.OnSSLServerAuthenticate(connection, out cert, out clientAuthenticate, ref checkRevocation); //----- Authneticate SSL! SslStream ssl = new SslStream(new NetworkStream(connection.Socket)); ssl.BeginAuthenticateAsServer(cert, clientAuthenticate, System.Security.Authentication.SslProtocols.Default, checkRevocation, new AsyncCallback(SslAuthenticateCallback), new AuthenticateCallbackData(connection, ssl, HostType.htServer)); } } }