Esempio n. 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());
                }
            }
        }
Esempio n. 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();
        }
Esempio n. 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();
        }
Esempio n. 4
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);
        }
Esempio n. 5
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);
        }
Esempio n. 6
0
        public async Task Send(byte[] packet, TeleSharp.TL.TLMethod request, CancellationToken token = default(CancellationToken))
        {
            token.ThrowIfCancellationRequested();

            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(), token).ConfigureAwait(false);
                }
            }
        }
Esempio n. 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 (FloodException ex)
                {
                    var wait = ex.TimeToWait.Add(TimeSpan.FromSeconds(1));
                    Thread.Sleep(wait);
                    messageReader.BaseStream.Position = beginPosition + innerLength;
                }
                catch (Exception e)
                {
                    //	logger.error("failed to process message in contailer: {0}", e);
                    messageReader.BaseStream.Position = beginPosition + innerLength;
                }
            }

            return(false);
        }
Esempio n. 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);
        }
Esempio n. 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);
        }
Esempio n. 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);
        }
Esempio n. 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);
        }
Esempio n. 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(OnInternalUpdate(messageId, sequence, messageReader));

            default:
                //logger.debug("unknown message: {0}", code);
                return(false);
            }
        }