From 820bda614c8cb3b787804a7b83ba1f4aff967ac5 Mon Sep 17 00:00:00 2001 From: Aurimas Date: Fri, 24 Feb 2017 16:24:56 +0100 Subject: [PATCH 1/4] Some generic exceptions refactored into custom and specific exceptions --- TLSharp.Core/Auth/Step3_CompleteDHExchange.cs | 9 +++- TLSharp.Core/Network/MtProtoSender.cs | 46 ++++++++++++++++++- TLSharp.Core/Network/TcpTransport.cs | 18 +++++++- 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs b/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs index 8ba8f5a3..b881e404 100644 --- a/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs +++ b/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs @@ -175,7 +175,7 @@ public Step3_Response FromBytes(byte[] response) if (!newNonceHash1.SequenceEqual(newNonceHashCalculated)) { - throw new InvalidOperationException("invalid new nonce hash"); + throw new InvalidNewNonceHashException(); } //logger.info("generated new auth key: {0}", gab); @@ -206,4 +206,11 @@ public Step3_Response FromBytes(byte[] response) } } } + internal class InvalidNewNonceHashException : Exception + { + internal InvalidNewNonceHashException() : base($"invalid new nonce hash") + { + + } + } } diff --git a/TLSharp.Core/Network/MtProtoSender.cs b/TLSharp.Core/Network/MtProtoSender.cs index 8a959caa..8ecbd710 100644 --- a/TLSharp.Core/Network/MtProtoSender.cs +++ b/TLSharp.Core/Network/MtProtoSender.cs @@ -110,7 +110,7 @@ private Tuple DecodeMessage(byte[] body) using (var inputReader = new BinaryReader(inputStream)) { if (inputReader.BaseStream.Length < 8) - throw new InvalidOperationException($"Can't decode packet"); + throw new DecodePacketException(); ulong remoteAuthKeyId = inputReader.ReadUInt64(); // TODO: check auth key id byte[] msgKey = inputReader.ReadBytes(16); // TODO: check msg_key correctness @@ -313,6 +313,15 @@ private bool HandleRpcResult(ulong messageId, int sequence, BinaryReader message { throw new CloudPasswordNeededException("This Account has Cloud Password !"); } + else if (errorMessage == "AUTH_KEY_UNREGISTERED") + { + // + throw new AuthKeyUnregisteredException(); + } + else if (errorMessage == "RPC_MCGET_FAIL") + { + throw new RpcMcGetFailException(); + } else { throw new InvalidOperationException(errorMessage); @@ -378,7 +387,7 @@ private bool HandleBadMsgNotification(ulong messageId, int sequence, BinaryReade case 20: throw new InvalidOperationException("message too old, and it cannot be verified whether the server has received a message with this msg_id or not"); case 32: - throw new InvalidOperationException("msg_seqno too low (the server has already received a message with a lower msg_id but with either a higher or an equal and odd seqno)"); + throw new MsgSeqnoTooLowException(); case 33: throw new InvalidOperationException(" msg_seqno too high (similarly, there is a message with a higher msg_id but with either a lower or an equal and odd seqno)"); case 34: @@ -535,6 +544,39 @@ internal FloodException(TimeSpan timeToWait) } } + internal class DecodePacketException : Exception + { + internal DecodePacketException() : base($"Can't decode packet.") + { + + } + } + public class AuthKeyUnregisteredException : Exception + { + internal AuthKeyUnregisteredException() : base($"Auth key is unregistered.") + { + + } + } + + internal class RpcMcGetFailException : Exception + { + internal RpcMcGetFailException() : base($"Rpc Mc Get Fail.") + { + + } + } + + internal class MsgSeqnoTooLowException : Exception + { + internal MsgSeqnoTooLowException() : base($"msg_seqno too low (the server has already received a message with a lower msg_id but with either a higher or an equal and odd seqno)") + { + + } + } + + + internal abstract class DataCenterMigrationException : Exception { internal int DC { get; private set; } diff --git a/TLSharp.Core/Network/TcpTransport.cs b/TLSharp.Core/Network/TcpTransport.cs index 254153ed..c297c47c 100644 --- a/TLSharp.Core/Network/TcpTransport.cs +++ b/TLSharp.Core/Network/TcpTransport.cs @@ -28,7 +28,7 @@ public TcpTransport(string address, int port, TcpClientConnectionHandler handler public async Task Send(byte[] packet) { if (!_tcpClient.Connected) - throw new InvalidOperationException("Client not connected to server."); + throw new TcpClientNotConnectedException(); var tcpMessage = new TcpMessage(sendCounter, packet); @@ -42,7 +42,7 @@ public async Task Receieve() var packetLengthBytes = new byte[4]; if (await stream.ReadAsync(packetLengthBytes, 0, 4) != 4) - throw new InvalidOperationException("Couldn't read the packet length"); + throw new TcpClientCouldntReadPacketLengthException(); int packetLength = BitConverter.ToInt32(packetLengthBytes, 0); var seqBytes = new byte[4]; @@ -92,4 +92,18 @@ public void Dispose() _tcpClient.Close(); } } + internal class TcpClientNotConnectedException : Exception + { + internal TcpClientNotConnectedException() : base($"Client not connected to server.") + { + + } + } + internal class TcpClientCouldntReadPacketLengthException : Exception + { + internal TcpClientCouldntReadPacketLengthException() : base($"Couldn't read the packet length") + { + + } + } } From 6493b1a82cc28942a0cd5f5c8f73770400d6abfb Mon Sep 17 00:00:00 2001 From: mykolasglinskis Date: Wed, 29 Mar 2017 09:58:16 +0200 Subject: [PATCH 2/4] Update Step3_CompleteDHExchange.cs --- TLSharp.Core/Auth/Step3_CompleteDHExchange.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs b/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs index b881e404..fb23613a 100644 --- a/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs +++ b/TLSharp.Core/Auth/Step3_CompleteDHExchange.cs @@ -208,7 +208,7 @@ public Step3_Response FromBytes(byte[] response) } internal class InvalidNewNonceHashException : Exception { - internal InvalidNewNonceHashException() : base($"invalid new nonce hash") + internal InvalidNewNonceHashException() : base("invalid new nonce hash") { } From b24167d2937b94ab8a6a72561bfc3a40d14a41aa Mon Sep 17 00:00:00 2001 From: mykolasglinskis Date: Wed, 29 Mar 2017 09:59:20 +0200 Subject: [PATCH 3/4] Update MtProtoSender.cs --- TLSharp.Core/Network/MtProtoSender.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/TLSharp.Core/Network/MtProtoSender.cs b/TLSharp.Core/Network/MtProtoSender.cs index 8ecbd710..4f34af15 100644 --- a/TLSharp.Core/Network/MtProtoSender.cs +++ b/TLSharp.Core/Network/MtProtoSender.cs @@ -546,14 +546,14 @@ internal FloodException(TimeSpan timeToWait) internal class DecodePacketException : Exception { - internal DecodePacketException() : base($"Can't decode packet.") + internal DecodePacketException() : base("Can't decode packet.") { } } public class AuthKeyUnregisteredException : Exception { - internal AuthKeyUnregisteredException() : base($"Auth key is unregistered.") + internal AuthKeyUnregisteredException() : base("Auth key is unregistered.") { } @@ -561,7 +561,7 @@ internal AuthKeyUnregisteredException() : base($"Auth key is unregistered.") internal class RpcMcGetFailException : Exception { - internal RpcMcGetFailException() : base($"Rpc Mc Get Fail.") + internal RpcMcGetFailException() : base("Rpc Mc Get Fail.") { } @@ -569,7 +569,7 @@ internal RpcMcGetFailException() : base($"Rpc Mc Get Fail.") internal class MsgSeqnoTooLowException : Exception { - internal MsgSeqnoTooLowException() : base($"msg_seqno too low (the server has already received a message with a lower msg_id but with either a higher or an equal and odd seqno)") + internal MsgSeqnoTooLowException() : base("msg_seqno too low (the server has already received a message with a lower msg_id but with either a higher or an equal and odd seqno)") { } @@ -613,4 +613,4 @@ internal UserMigrationException(int dc) { } } -} \ No newline at end of file +} From 709d2479e99f3da4f567f019fb8c23cb4ed8e627 Mon Sep 17 00:00:00 2001 From: mykolasglinskis Date: Wed, 29 Mar 2017 09:59:57 +0200 Subject: [PATCH 4/4] Update TcpTransport.cs --- TLSharp.Core/Network/TcpTransport.cs | 216 +++++++++++++-------------- 1 file changed, 108 insertions(+), 108 deletions(-) diff --git a/TLSharp.Core/Network/TcpTransport.cs b/TLSharp.Core/Network/TcpTransport.cs index c297c47c..6d0d74a7 100644 --- a/TLSharp.Core/Network/TcpTransport.cs +++ b/TLSharp.Core/Network/TcpTransport.cs @@ -1,109 +1,109 @@ -using System; -using System.Net; -using System.Net.Sockets; -using System.Threading.Tasks; - -namespace TLSharp.Core.Network -{ - public delegate TcpClient TcpClientConnectionHandler(string address, int port); - - public class TcpTransport : IDisposable - { - private readonly TcpClient _tcpClient; - private int sendCounter = 0; - - public TcpTransport(string address, int port, TcpClientConnectionHandler handler = null) - { - if (handler == null) - { - _tcpClient = new TcpClient(); - - var ipAddress = IPAddress.Parse(address); - _tcpClient.Connect(ipAddress, port); - } - else - _tcpClient = handler(address, port); - } - - public async Task Send(byte[] packet) - { - if (!_tcpClient.Connected) - throw new TcpClientNotConnectedException(); - - var tcpMessage = new TcpMessage(sendCounter, packet); - - await _tcpClient.GetStream().WriteAsync(tcpMessage.Encode(), 0, tcpMessage.Encode().Length); - sendCounter++; - } - - public async Task Receieve() - { - var stream = _tcpClient.GetStream(); - - var packetLengthBytes = new byte[4]; - if (await stream.ReadAsync(packetLengthBytes, 0, 4) != 4) - throw new TcpClientCouldntReadPacketLengthException(); - int packetLength = BitConverter.ToInt32(packetLengthBytes, 0); - - var seqBytes = new byte[4]; - if (await stream.ReadAsync(seqBytes, 0, 4) != 4) - throw new InvalidOperationException("Couldn't read the sequence"); - int seq = BitConverter.ToInt32(seqBytes, 0); - - int readBytes = 0; - var body = new byte[packetLength - 12]; - int neededToRead = packetLength - 12; - - do - { - var bodyByte = new byte[packetLength - 12]; - var availableBytes = await stream.ReadAsync(bodyByte, 0, neededToRead); - neededToRead -= availableBytes; - Buffer.BlockCopy(bodyByte, 0, body, readBytes, availableBytes); - readBytes += availableBytes; - } - while (readBytes != packetLength - 12); - - var crcBytes = new byte[4]; - if (await stream.ReadAsync(crcBytes, 0, 4) != 4) - throw new InvalidOperationException("Couldn't read the crc"); - int checksum = BitConverter.ToInt32(crcBytes, 0); - - byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + body.Length]; - - Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length); - Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length); - Buffer.BlockCopy(body, 0, rv, packetLengthBytes.Length + seqBytes.Length, body.Length); - var crc32 = new Ionic.Crc.CRC32(); - crc32.SlurpBlock(rv, 0, rv.Length); - var validChecksum = crc32.Crc32Result; - - if (checksum != validChecksum) - { - throw new InvalidOperationException("invalid checksum! skip"); - } - - return new TcpMessage(seq, body); - } - - public void Dispose() - { - if (_tcpClient.Connected) - _tcpClient.Close(); +using System; +using System.Net; +using System.Net.Sockets; +using System.Threading.Tasks; + +namespace TLSharp.Core.Network +{ + public delegate TcpClient TcpClientConnectionHandler(string address, int port); + + public class TcpTransport : IDisposable + { + private readonly TcpClient _tcpClient; + private int sendCounter = 0; + + public TcpTransport(string address, int port, TcpClientConnectionHandler handler = null) + { + if (handler == null) + { + _tcpClient = new TcpClient(); + + var ipAddress = IPAddress.Parse(address); + _tcpClient.Connect(ipAddress, port); + } + else + _tcpClient = handler(address, port); } - } - internal class TcpClientNotConnectedException : Exception - { - internal TcpClientNotConnectedException() : base($"Client not connected to server.") - { - - } - } - internal class TcpClientCouldntReadPacketLengthException : Exception - { - internal TcpClientCouldntReadPacketLengthException() : base($"Couldn't read the packet length") - { - - } - } -} + + public async Task Send(byte[] packet) + { + if (!_tcpClient.Connected) + throw new TcpClientNotConnectedException(); + + var tcpMessage = new TcpMessage(sendCounter, packet); + + await _tcpClient.GetStream().WriteAsync(tcpMessage.Encode(), 0, tcpMessage.Encode().Length); + sendCounter++; + } + + public async Task Receieve() + { + var stream = _tcpClient.GetStream(); + + var packetLengthBytes = new byte[4]; + if (await stream.ReadAsync(packetLengthBytes, 0, 4) != 4) + throw new TcpClientCouldntReadPacketLengthException(); + int packetLength = BitConverter.ToInt32(packetLengthBytes, 0); + + var seqBytes = new byte[4]; + if (await stream.ReadAsync(seqBytes, 0, 4) != 4) + throw new InvalidOperationException("Couldn't read the sequence"); + int seq = BitConverter.ToInt32(seqBytes, 0); + + int readBytes = 0; + var body = new byte[packetLength - 12]; + int neededToRead = packetLength - 12; + + do + { + var bodyByte = new byte[packetLength - 12]; + var availableBytes = await stream.ReadAsync(bodyByte, 0, neededToRead); + neededToRead -= availableBytes; + Buffer.BlockCopy(bodyByte, 0, body, readBytes, availableBytes); + readBytes += availableBytes; + } + while (readBytes != packetLength - 12); + + var crcBytes = new byte[4]; + if (await stream.ReadAsync(crcBytes, 0, 4) != 4) + throw new InvalidOperationException("Couldn't read the crc"); + int checksum = BitConverter.ToInt32(crcBytes, 0); + + byte[] rv = new byte[packetLengthBytes.Length + seqBytes.Length + body.Length]; + + Buffer.BlockCopy(packetLengthBytes, 0, rv, 0, packetLengthBytes.Length); + Buffer.BlockCopy(seqBytes, 0, rv, packetLengthBytes.Length, seqBytes.Length); + Buffer.BlockCopy(body, 0, rv, packetLengthBytes.Length + seqBytes.Length, body.Length); + var crc32 = new Ionic.Crc.CRC32(); + crc32.SlurpBlock(rv, 0, rv.Length); + var validChecksum = crc32.Crc32Result; + + if (checksum != validChecksum) + { + throw new InvalidOperationException("invalid checksum! skip"); + } + + return new TcpMessage(seq, body); + } + + public void Dispose() + { + if (_tcpClient.Connected) + _tcpClient.Close(); + } + } + internal class TcpClientNotConnectedException : Exception + { + internal TcpClientNotConnectedException() : base("Client not connected to server.") + { + + } + } + internal class TcpClientCouldntReadPacketLengthException : Exception + { + internal TcpClientCouldntReadPacketLengthException() : base("Couldn't read the packet length") + { + + } + } +}