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()); } } }
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(); }
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(); }
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); }
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); }
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); } } }
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); }
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); }
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); }
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); }
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); }
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); } }