Exemple #1
0
        public async Task Send(byte[] packet, TeleSharp.TL.TLMethod request)
        {
            request.MessageId = _session.GetNewMessageId();

            byte[] msgKey;
            byte[] ciphertext;
            using (MemoryStream plaintextPacket = makeMemory(8 + 8 + 8 + 4 + 4 + packet.Length))
            {
                using (BinaryWriter plaintextWriter = new BinaryWriter(plaintextPacket))
                {
                    plaintextWriter.Write(_session.Salt);
                    plaintextWriter.Write(_session.Id);
                    plaintextWriter.Write(request.MessageId);
                    plaintextWriter.Write(GenerateSequence(request.Confirmed));
                    plaintextWriter.Write(packet.Length);
                    plaintextWriter.Write(packet);

                    msgKey     = Helpers.CalcMsgKey(plaintextPacket.GetBuffer());
                    ciphertext = AES.EncryptAES(Helpers.CalcKey(_session.AuthKey.Data, msgKey, true), plaintextPacket.GetBuffer());
                }
            }

            using (MemoryStream ciphertextPacket = makeMemory(8 + 16 + ciphertext.Length))
            {
                using (BinaryWriter writer = new BinaryWriter(ciphertextPacket))
                {
                    writer.Write(_session.AuthKey.Id);
                    writer.Write(msgKey);
                    writer.Write(ciphertext);

                    await _transport.Send(ciphertextPacket.GetBuffer());
                }
            }
        }
Exemple #2
0
        public async Task Send(TeleSharp.TL.TLMethod request)
        {
            // TODO: refactor
            if (needConfirmation.Any())
            {
                var ackRequest = new AckRequest(needConfirmation);
                using (var memory = new MemoryStream())
                    using (var writer = new BinaryWriter(memory))
                    {
                        ackRequest.SerializeBody(writer);
                        await Send(memory.ToArray(), ackRequest);

                        needConfirmation.Clear();
                    }
            }


            using (var memory = new MemoryStream())
                using (var writer = new BinaryWriter(memory))
                {
                    request.SerializeBody(writer);
                    await Send(memory.ToArray(), request);
                }

            _session.Save();
        }
Exemple #3
0
        public async Task Send(TeleSharp.TL.TLMethod request, CancellationToken token = default(CancellationToken))
        {
            token.ThrowIfCancellationRequested();

            // TODO: refactor
            if (needConfirmation.Any())
            {
                var ackRequest = new AckRequest(needConfirmation);
                using (var memory = new MemoryStream())
                    using (var writer = new BinaryWriter(memory))
                    {
                        ackRequest.SerializeBody(writer);
                        await Send(memory.ToArray(), ackRequest, token).ConfigureAwait(false);

                        needConfirmation.Clear();
                    }
            }


            using (var memory = new MemoryStream())
                using (var writer = new BinaryWriter(memory))
                {
                    request.SerializeBody(writer);
                    await Send(memory.ToArray(), request, token).ConfigureAwait(false);
                }

            _session.Save();
        }
Exemple #4
0
        public async Task Send(TeleSharp.TL.TLMethod request)
        {
            using (var memory = new MemoryStream())
                using (var writer = new BinaryWriter(memory))
                {
                    request.SerializeBody(writer);
                    await Send(memory.ToArray(), request);
                }

            _session.Save();
        }
Exemple #5
0
        public async Task <byte[]> Receive(TeleSharp.TL.TLMethod request)
        {
            while (!request.ConfirmReceived)
            {
                var result = DecodeMessage((await _transport.Receieve()).Body);

                using (var messageStream = new MemoryStream(result.Item1, false))
                    using (var messageReader = new BinaryReader(messageStream))
                    {
                        processMessage(result.Item2, result.Item3, messageReader, request);
                    }
            }

            return(null);
        }
Exemple #6
0
        public async Task <byte[]> Receive(TeleSharp.TL.TLMethod request, CancellationToken token = default(CancellationToken))
        {
            while (!request.ConfirmReceived)
            {
                var result = DecodeMessage((await _transport.Receive(token).ConfigureAwait(false)).Body);

                using (var messageStream = new MemoryStream(result.Item1, false))
                    using (var messageReader = new BinaryReader(messageStream))
                    {
                        processMessage(result.Item2, result.Item3, messageReader, request, token);
                    }

                token.ThrowIfCancellationRequested();
            }

            return(null);
        }
Exemple #7
0
        private bool HandleContainer(ulong messageId, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request)
        {
            uint code = messageReader.ReadUInt32();
            int  size = messageReader.ReadInt32();

            for (int i = 0; i < size; i++)
            {
                ulong innerMessageId = messageReader.ReadUInt64();
                int   innerSequence  = messageReader.ReadInt32();
                int   innerLength    = messageReader.ReadInt32();
                long  beginPosition  = messageReader.BaseStream.Position;
                try
                {
                    if (!processMessage(innerMessageId, sequence, messageReader, request))
                    {
                        messageReader.BaseStream.Position = beginPosition + innerLength;
                    }
                }
                catch (Exception e)
                {
                    //	logger.error("failed to process message in container: {0}", e);
                    messageReader.BaseStream.Position = beginPosition + innerLength;
                }
            }

            return(false);
        }
Exemple #8
0
        private bool HandlePong(ulong messageId, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request)
        {
            uint  code  = messageReader.ReadUInt32();
            ulong msgId = messageReader.ReadUInt64();

            if (msgId == (ulong)request.MessageId)
            {
                request.ConfirmReceived = true;
            }

            return(false);
        }
Exemple #9
0
        private bool HandleBadServerSalt(ulong messageId, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request)
        {
            uint  code        = messageReader.ReadUInt32();
            ulong badMsgId    = messageReader.ReadUInt64();
            int   badMsgSeqNo = messageReader.ReadInt32();
            int   errorCode   = messageReader.ReadInt32();
            ulong newSalt     = messageReader.ReadUInt64();

            //logger.debug("bad_server_salt: msgid {0}, seq {1}, errorcode {2}, newsalt {3}", badMsgId, badMsgSeqNo, errorCode, newSalt);

            _session.Salt = newSalt;

            //resend
            Send(request);

            /*
             * if(!runningRequests.ContainsKey(badMsgId)) {
             *  logger.debug("bad server salt on unknown message");
             *  return true;
             * }
             */


            //MTProtoRequest request = runningRequests[badMsgId];
            //request.OnException(new MTProtoBadServerSaltException(salt));

            return(true);
        }
Exemple #10
0
        private bool HandleRpcResult(ulong messageId, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request)
        {
            uint  code      = messageReader.ReadUInt32();
            ulong requestId = messageReader.ReadUInt64();

            if (requestId == (ulong)request.MessageId)
            {
                request.ConfirmReceived = true;
            }

            //throw new NotImplementedException();

            /*
             *          lock (runningRequests)
             *          {
             *                  if (!runningRequests.ContainsKey(requestId))
             *                  {
             *                          logger.warning("rpc response on unknown request: {0}", requestId);
             *                          messageReader.BaseStream.Position -= 12;
             *                          return false;
             *                  }
             *
             *                  request = runningRequests[requestId];
             *                  runningRequests.Remove(requestId);
             *          }
             */

            uint innerCode = messageReader.ReadUInt32();

            if (innerCode == 0x2144ca19)
            { // rpc_error
                int    errorCode    = messageReader.ReadInt32();
                string errorMessage = Serializers.String.read(messageReader);

                if (errorMessage.StartsWith("FLOOD_WAIT_"))
                {
                    var resultString = Regex.Match(errorMessage, @"\d+").Value;
                    var seconds      = int.Parse(resultString);
                    throw new FloodException(TimeSpan.FromSeconds(seconds));
                }
                else if (errorMessage.StartsWith("PHONE_MIGRATE_"))
                {
                    var resultString = Regex.Match(errorMessage, @"\d+").Value;
                    var dcIdx        = int.Parse(resultString);
                    throw new PhoneMigrationException(dcIdx);
                }
                else if (errorMessage.StartsWith("FILE_MIGRATE_"))
                {
                    var resultString = Regex.Match(errorMessage, @"\d+").Value;
                    var dcIdx        = int.Parse(resultString);
                    throw new FileMigrationException(dcIdx);
                }
                else if (errorMessage.StartsWith("USER_MIGRATE_"))
                {
                    var resultString = Regex.Match(errorMessage, @"\d+").Value;
                    var dcIdx        = int.Parse(resultString);
                    throw new UserMigrationException(dcIdx);
                }
                else if (errorMessage.StartsWith("NETWORK_MIGRATE_"))
                {
                    var resultString = Regex.Match(errorMessage, @"\d+").Value;
                    var dcIdx        = int.Parse(resultString);
                    throw new NetworkMigrationException(dcIdx);
                }
                else if (errorMessage == "PHONE_CODE_INVALID")
                {
                    throw new InvalidPhoneCodeException("The numeric code used to authenticate does not match the numeric code sent by SMS/Telegram");
                }
                else if (errorMessage == "SESSION_PASSWORD_NEEDED")
                {
                    throw new CloudPasswordNeededException("This Account has Cloud Password !");
                }
                else
                {
                    throw new InvalidOperationException(errorMessage);
                }
            }
            else if (innerCode == 0x3072cfa1)
            {
                try
                {
                    // gzip_packed
                    byte[] packedData = Serializers.Bytes.read(messageReader);
                    using (var ms = new MemoryStream())
                    {
                        using (var packedStream = new MemoryStream(packedData, false))
                            using (var zipStream = new GZipStream(packedStream, CompressionMode.Decompress))
                            {
                                zipStream.CopyTo(ms);
                                ms.Position = 0;
                            }
                        using (var compressedReader = new BinaryReader(ms))
                        {
                            request.DeserializeResponse(compressedReader);
                        }
                    }
                }
                catch (ZlibException ex)
                {
                }
            }
            else
            {
                messageReader.BaseStream.Position -= 4;
                request.DeserializeResponse(messageReader);
            }

            return(false);
        }
Exemple #11
0
        private bool HandleGzipPacked(ulong messageId, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request)
        {
            uint code = messageReader.ReadUInt32();

            byte[] packedData = GZipStream.UncompressBuffer(Serializers.Bytes.read(messageReader));
            using (MemoryStream packedStream = new MemoryStream(packedData, false))
                using (BinaryReader compressedReader = new BinaryReader(packedStream))
                {
                    processMessage(messageId, sequence, compressedReader, request);
                }

            return(true);
        }
Exemple #12
0
        private bool processMessage(ulong messageId, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request)
        {
            // TODO: check salt
            // TODO: check sessionid
            // TODO: check seqno

            //logger.debug("processMessage: msg_id {0}, sequence {1}, data {2}", BitConverter.ToString(((MemoryStream)messageReader.BaseStream).GetBuffer(), (int) messageReader.BaseStream.Position, (int) (messageReader.BaseStream.Length - messageReader.BaseStream.Position)).Replace("-","").ToLower());
            needConfirmation.Add(messageId);

            uint code = messageReader.ReadUInt32();

            messageReader.BaseStream.Position -= 4;
            switch (code)
            {
            case 0x73f1f8dc:     // container
                                 //logger.debug("MSG container");
                return(HandleContainer(messageId, sequence, messageReader, request));

            case 0x7abe77ec:     // ping
                                 //logger.debug("MSG ping");
                return(HandlePing(messageId, sequence, messageReader));

            case 0x347773c5:     // pong
                                 //logger.debug("MSG pong");
                return(HandlePong(messageId, sequence, messageReader, request));

            case 0xae500895:     // future_salts
                                 //logger.debug("MSG future_salts");
                return(HandleFutureSalts(messageId, sequence, messageReader));

            case 0x9ec20908:     // new_session_created
                                 //logger.debug("MSG new_session_created");
                return(HandleNewSessionCreated(messageId, sequence, messageReader));

            case 0x62d6b459:     // msgs_ack
                                 //logger.debug("MSG msds_ack");
                return(HandleMsgsAck(messageId, sequence, messageReader));

            case 0xedab447b:     // bad_server_salt
                                 //logger.debug("MSG bad_server_salt");
                return(HandleBadServerSalt(messageId, sequence, messageReader, request));

            case 0xa7eff811:     // bad_msg_notification
                                 //logger.debug("MSG bad_msg_notification");
                return(HandleBadMsgNotification(messageId, sequence, messageReader));

            case 0x276d3ec6:     // msg_detailed_info
                                 //logger.debug("MSG msg_detailed_info");
                return(HandleMsgDetailedInfo(messageId, sequence, messageReader));

            case 0xf35c6d01:     // rpc_result
                                 //logger.debug("MSG rpc_result");
                return(HandleRpcResult(messageId, sequence, messageReader, request));

            case 0x3072cfa1:     // gzip_packed
                                 //logger.debug("MSG gzip_packed");
                return(HandleGzipPacked(messageId, sequence, messageReader, request));

            case 0xe317af7e:
            case 0xd3f45784:
            case 0x2b2fbd4e:
            case 0x78d4dec1:
            case 0x725b04c3:
            case 0x74ae4240:
                return(HandleUpdate(messageId, sequence, messageReader));

            default:
                //logger.debug("unknown message: {0}", code);
                return(false);
            }
        }
Exemple #13
0
        private bool HandleRpcResult(ulong messageId, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request)
        {
            uint  code      = messageReader.ReadUInt32();
            ulong requestId = messageReader.ReadUInt64();

            if (requestId == (ulong)request.MessageId)
            {
                request.ConfirmReceived = true;
            }

            //throw new NotImplementedException();

            /*
             *          lock (runningRequests)
             *          {
             *                  if (!runningRequests.ContainsKey(requestId))
             *                  {
             *                          logger.warning("rpc response on unknown request: {0}", requestId);
             *                          messageReader.BaseStream.Position -= 12;
             *                          return false;
             *                  }
             *
             *                  request = runningRequests[requestId];
             *                  runningRequests.Remove(requestId);
             *          }
             */

            uint innerCode = messageReader.ReadUInt32();

            if (innerCode == 0x2144ca19)
            { // rpc_error
                int    errorCode    = messageReader.ReadInt32();
                string errorMessage = Serializers.String.read(messageReader);

                if (errorMessage.StartsWith("FLOOD_WAIT_"))
                {
                    var resultString = Regex.Match(errorMessage, @"\d+").Value;
                    var seconds      = int.Parse(resultString);
                    Debug.WriteLine($"Should wait {seconds} sec.");
                    Thread.Sleep(1000 * seconds);
                }
                else if (errorMessage.StartsWith("PHONE_MIGRATE_"))
                {
                    var resultString = Regex.Match(errorMessage, @"\d+").Value;
                    var dcIdx        = int.Parse(resultString);
                    var exception    = new InvalidOperationException($"Your phone number registered to {dcIdx} dc. Please update settings. See https://github.com/sochix/TLSharp#i-get-an-error-migrate_x for details.");
                    exception.Data.Add("dcId", dcIdx);
                    throw exception;
                }
                else
                {
                    throw new InvalidOperationException(errorMessage);
                }
            }
            else if (innerCode == 0x3072cfa1)
            {
                try
                {
                    // gzip_packed
                    byte[] packedData = Serializers.Bytes.read(messageReader);
                    using (var ms = new MemoryStream())
                    {
                        using (var packedStream = new MemoryStream(packedData, false))
                            using (var zipStream = new GZipStream(packedStream, CompressionMode.Decompress))
                            {
                                zipStream.CopyTo(ms);
                                ms.Position = 0;
                            }
                        using (var compressedReader = new BinaryReader(ms))
                        {
                            request.deserializeResponse(compressedReader);
                        }
                    }
                }
                catch (ZlibException ex)
                {
                }
            }
            else
            {
                messageReader.BaseStream.Position -= 4;
                request.deserializeResponse(messageReader);
            }

            return(false);
        }
Exemple #14
0
 private bool HandleUpdate(uint code, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request)
 {
     try
     {
         var update = ParseUpdate(code, messageReader);
         if (update != null && UpdatesEvent != null)
         {
             UpdatesEvent(update);
         }
         return(true);
     }
     catch (Exception ex)
     {
         logger.Debug($"HandleUpdate failed: {ex.ToString()}");
     }
     return(false);
 }
Exemple #15
0
        public async Task Send(TeleSharp.TL.TLMethod request)
        {
            // TODO: refactor
            if (needConfirmation.Any())
            {
                var ackRequest = new AckRequest(needConfirmation);
                using (var memory = new MemoryStream())
                    using (var writer = new BinaryWriter(memory))
                    {
                        ackRequest.SerializeBody(writer);
                        await Send(memory.ToArray(), ackRequest);

                        needConfirmation.Clear();
                    }
            }


            //using (var memory = new MemoryStream())
            //using (var writer = new BinaryWriter(memory))
            //{
            //    request.SerializeBody(writer);
            //    await Send(memory.ToArray(), request);
            //}



            TaskCompletionSource <bool> responseSource;

            using (var memory = new MemoryStream())
                using (var writer = new BinaryWriter(memory))
                {
                    //var messageId = _session.GetNewMessageId();
                    //request.MessageId = messageId;

                    //if (request.GetType() == typeof(TeleSharp.TL.TLRequestInvokeWithLayer))
                    //{
                    //    connectMessageID = messageId;
                    //}


                    request.SerializeBody(writer);
                    request.MessageId = _session.GetNewMessageId();

                    Debug.WriteLine($"Send request - {request.MessageId}");
                    responseSource = new TaskCompletionSource <bool>();
                    runningRequests.Add(request.MessageId, Tuple.Create(request, responseSource));

                    await Send(memory.ToArray(), request);

                    Debug.WriteLine("sended");
                }

            await responseSource.Task;

            Debug.WriteLine("complete");
            if (runningRequests.ContainsKey(request.MessageId))
            {
                runningRequests.Remove(request.MessageId);
            }
            Debug.WriteLine("request removed from queue");

            _session.Save();
            Debug.WriteLine("session saved");
        }
Exemple #16
0
 private bool HandleUpdate(uint code, int sequence, BinaryReader messageReader, TeleSharp.TL.TLMethod request)
 {
     try
     {
         var update = ParseUpdate(code, messageReader);
         if (update != null && UpdatesEvent != null)
         {
             UpdatesEvent(update);
         }
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex);
     }
     return(false);
 }