private void BotClient_TermsOfServiceRequestedEventHandler(object sender, TLObjectEventArgs e) { //if (MessageBox.Show(e.TermsOfServiceText, "GlassTL Userbot", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) //{ // return; //} //botClient.SendAcceptTOS(e.TermsOfServiceId); }
private void BotClient_FirstNameRequestedEventHandler(object sender, TLObjectEventArgs e) { authCodeTextBox.Enabled = false; verifyAuthCodeButton.Enabled = false; changeMethodLinkLabel.Enabled = false; firstNameTextBox.Enabled = true; lastNameTextBox.Enabled = true; verifyNameButton.Enabled = true; }
private void BotClient_AuthCodeRequestedEventHandler(object sender, TLObjectEventArgs e) { phoneNumberTextBox.Enabled = false; loginButton.Enabled = false; authCodeTextBox.Text = ""; authCodeTextBox.Enabled = true; verifyAuthCodeButton.Enabled = true; changeMethodLinkLabel.Enabled = true; AddToLog(e.ToString()); MessageBox.Show((string)e.TLObject["type"]["_"]); }
private void BotClient_CloudPasswordRequestedEventHandler(object sender, TLObjectEventArgs e) { authCodeTextBox.Enabled = false; verifyAuthCodeButton.Enabled = false; changeMethodLinkLabel.Enabled = false; passwordTextBox.Text = ""; passwordTextBox.Enabled = true; passwordTextBox.Tag = (e.TLObject["hint"] != null && ((string)e.TLObject["hint"]).Length > 0) ? $"A Cloud Password is set on the account:\n\n{(string)e.TLObject["hint"]}" : ""; verifyPasswordButton.Enabled = true; viewHintLinkLabel.Enabled = true; ViewHintLinkLabel_LinkClicked(sender, null); }
private void BotClient_UpdateUserEventHandler(object sender, TLObjectEventArgs e) { authCodeTextBox.Enabled = false; verifyAuthCodeButton.Enabled = false; changeMethodLinkLabel.Enabled = false; firstNameTextBox.Enabled = false; lastNameTextBox.Enabled = false; verifyNameButton.Enabled = false; passwordTextBox.Enabled = false; verifyPasswordButton.Enabled = false; viewHintLinkLabel.Enabled = false; phoneNumberTextBox.Text = (string)e.TLObject["phone_number"]; firstNameTextBox.Text = (string)e.TLObject["first_name"]; lastNameTextBox.Text = (string)(e.TLObject["last_name"] ?? ""); Text = (string)e.TLObject["first_name"] + ((((string)e.TLObject["last_name"] ?? "").Length > 0) ? $" {(string)e.TLObject["last_name"]}" : "") + " - " + e.TLObject["id"]; //AddToLog(e.User.ToString()); }
private async void BotClient_NewMessageEventHandler(object sender, TLObjectEventArgs e) { try { if (RawUpdatesCheckbox.Checked) { AddToLog(e.TLObject.ToString()); } var FromUser = e.TLObject["from_user"]; var ToPeer = e.TLObject["to_peer"]; var FromName = ""; var ToName = ""; var FromId = 0; var ToId = 0; if (ToPeer.Value <string>("_") == "channel") { ToName = ToPeer.Value <string>("title"); } else { ToName = $"{ToPeer.Value<string>("first_name")} {ToPeer.Value<string>("last_name")}".Trim(); } FromName = FromUser.Type != JTokenType.Null ? $"{FromUser.Value<string>("first_name")} {FromUser.Value<string>("last_name")}".Trim() : default; if (string.IsNullOrEmpty(FromName)) { FromName = "No-Name"; } if (string.IsNullOrEmpty(ToName)) { ToName = "No-Name"; } FromId = FromUser.Type != JTokenType.Null ? FromUser.Value <int>("id") : default; ToId = ToPeer.Value <int>("id"); AddToLog($"{FromName} ({FromId}) -> {ToName} ({ToId}) >>> {e.TLObject["message"].Value<string>("message")}"); if (FromUser.Type == JTokenType.Null) { return; } if ((bool)e.TLObject["message"]["out"]) { return; } if (!(new long[] { 876650892, 960462, 295152997, 976906477 }).Contains((long)FromUser["id"])) { return; } //if (!(new long[] { 848427085, 234480941, 313742192, 537790376 }).Contains(FromId)) return; TLObject ShouldReplyTo; if ((int)botClient.CurrentUser["id"] == (int)ToPeer["id"]) { ShouldReplyTo = new TLObject(FromUser); } else { ShouldReplyTo = new TLObject(ToPeer); } switch ((string)e.TLObject["message"]["message"]) { case ";ping": var first = DateTime.Now; var UpdateEventArgs = await botClient.SendMessage(ShouldReplyTo, "<b>Status</b>\n\n<code>✅ Online</code>\n\n<i>(calculating lag...)</i>"); double lag = Math.Round((DateTime.Now - first).TotalMilliseconds, 2); UpdateEventArgs = await botClient.EditMessage(ShouldReplyTo, UpdateEventArgs, $"<b>Status</b>\n\n<code>✅ Online</code>\n\n(<i>reply took {lag}ms</i>)"); break; case ";code": await botClient.SendMessage(ShouldReplyTo, $"<code>{e.TLObject["message"].ToString()}</code>"); break; case ";whois": //long UserId = -335698371; //-10010356929597; //UpdateEventArgs u = await botClient.GetChat(UserId); //await botClient.SendMessage(ShouldReplyTo, u.RawUpdate.ToString()); break; default: break; } } catch (Exception ex) { } }
private void BotClient_ClientLoggedOutEventHandler(object sender, TLObjectEventArgs e) { MessageBox.Show("You have been logged out.", "GlassTL Userbot", MessageBoxButtons.OK, MessageBoxIcon.Information); }
private void BotClient_PhoneNumberRequestedEventHandler(object sender, TLObjectEventArgs e) { phoneNumberTextBox.Text = ""; phoneNumberTextBox.Enabled = true; loginButton.Enabled = true; }
private void Sender_TLObjectReceivedEvent(object sender, TLObjectEventArgs e) { // Ignore any data that we aren't expecting if (CurrentState == AuthenticationState.NotStarted) { Logger.Log(Logger.Level.Debug, $"Received authentication data unexpectedly. Skipping. Try restarting the connection."); return; } else if (MTSender == null) { // How did we get here if there's no sender? Hmm? var sad = new Exception("Unable to find a connection to Telegram. Skipping. Try restarting the connection."); Logger.Log(sad); Response.TrySetException(sad); CurrentState = AuthenticationState.NotStarted; return; } switch (CurrentState) { case AuthenticationState.PQRequest: // Deserialize the data var ResPQ = e.TLObject; Logger.Log(Logger.Level.Debug, $"Received TLObject {ResPQ["_"]}."); // Factorize the PQ into two prime factors and fail if we can't if (!Helpers.FindPQ((byte[])ResPQ["pq"], out JToken factorizedPair)) { var sad = new Exception($"Unable to find any valid factors of PQ: {ResPQ["pq"]}"); Logger.Log(sad); Response.TrySetException(sad); MTSender.TLObjectReceivedEvent -= Sender_TLObjectReceivedEvent; CurrentState = AuthenticationState.NotStarted; Logger.Log(Logger.Level.Debug, $"Unsubscribed from {nameof(MTSender.TLObjectReceivedEvent)} event"); Logger.Log(Logger.Level.Info, $"Auth aborted."); return; } // Compile the PQ information PQInnerData = schema.p_q_inner_data(new { pq = factorizedPair["pq"], p = factorizedPair["min"], q = factorizedPair["max"], nonce = ResPQ["nonce"], server_nonce = ResPQ["server_nonce"], new_nonce = Helpers.GenerateRandomBytes(32) }); // Encrypt the PQ information. // NOTE: Because the server responded with potentially more than one fingerprint, // this also returns the fingerprint that we are using. (var fingerpint, var EncryptedInnerData) = MTProto.Crypto.RSA.Encrypt(ResPQ["server_public_key_fingerprints"].ToObject <long[]>(), PQInnerData.Serialize()); Logger.Log(Logger.Level.Debug, $"Using Public RSA Key: {fingerpint}"); // Get ready for the next response CurrentState = AuthenticationState.ServerDHRequest; Logger.Log(Logger.Level.Debug, $"Submitting PQ factor to server"); // Compile the rest of the information and send to the server for grading MTSender.Send(schema.req_DH_params(new { nonce = ResPQ["nonce"], server_nonce = ResPQ["server_nonce"], p = factorizedPair["min"], q = factorizedPair["max"], public_key_fingerprint = fingerpint, encrypted_data = EncryptedInnerData })); break; case AuthenticationState.ServerDHRequest: // Make sure we have all the needed info if (PQInnerData == null) { var sad = new Exception("Unable to find the PQInnerData object from previous steps. Please restart the connection process"); Logger.Log(sad); Response.TrySetException(sad); MTSender.TLObjectReceivedEvent -= Sender_TLObjectReceivedEvent; CurrentState = AuthenticationState.NotStarted; Logger.Log(Logger.Level.Debug, $"Unsubscribed from {nameof(MTSender.TLObjectReceivedEvent)} event"); Logger.Log(Logger.Level.Info, $"Auth aborted."); return; } // Deserialize the data var ServerDHParams = e.TLObject; Logger.Log(Logger.Level.Debug, $"Received TLObject {ServerDHParams["_"]}."); // Determine the result if ((string)ServerDHParams["_"] != "server_DH_params_ok") { // Aaaand we failed to handle things correctly var sad = new Exception($"The server responded with a {ServerDHParams["_"]} response. We are unable to continue."); Logger.Log(sad); Response.TrySetException(sad); MTSender.TLObjectReceivedEvent -= Sender_TLObjectReceivedEvent; CurrentState = AuthenticationState.NotStarted; Logger.Log(Logger.Level.Debug, $"Unsubscribed from {nameof(MTSender.TLObjectReceivedEvent)} event"); Logger.Log(Logger.Level.Info, $"Auth aborted."); return; } Logger.Log(Logger.Level.Debug, $"Decrypting the DHInnerData"); var key = AES.GenerateKeyDataFromNonces((byte[])ServerDHParams["server_nonce"], (byte[])PQInnerData["new_nonce"]); var plaintextAnswer = AES.DecryptAES(key, (byte[])ServerDHParams["encrypted_answer"]); using (var memory = new MemoryStream(plaintextAnswer)) using (var reader = new BinaryReader(memory)) { var hashsum = reader.ReadBytes(20); ServerDHInnerData = TLObject.Deserialize(reader); } if (ServerDHInnerData == null) { var sad = new Exception("The server did not respond with valid DH Inner Data. We are unable to continue."); Logger.Log(sad); Response.TrySetException(sad); MTSender.TLObjectReceivedEvent -= Sender_TLObjectReceivedEvent; CurrentState = AuthenticationState.NotStarted; Logger.Log(Logger.Level.Debug, $"Unsubscribed from {nameof(MTSender.TLObjectReceivedEvent)} event"); Logger.Log(Logger.Level.Info, $"Auth aborted."); return; } if ((string)ServerDHInnerData["_"] != "server_DH_inner_data") { var sad = new Exception($"The server responded with a {ServerDHInnerData["_"]} response. We are unable to continue."); Logger.Log(sad); Response.TrySetException(sad); MTSender.TLObjectReceivedEvent -= Sender_TLObjectReceivedEvent; CurrentState = AuthenticationState.NotStarted; Logger.Log(Logger.Level.Debug, $"Unsubscribed from {nameof(MTSender.TLObjectReceivedEvent)} event"); Logger.Log(Logger.Level.Info, $"Auth aborted."); return; } Logger.Log(Logger.Level.Debug, $"Decrypted TLObject {ServerDHInnerData["_"]}."); TimeOffset = (int)ServerDHInnerData["server_time"] - (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; Logger.Log(Logger.Level.Debug, $"Updated Time Offset {TimeOffset}."); Logger.Log(Logger.Level.Debug, $"Calculating GAB"); var b = new BigInteger(1, Helpers.GenerateRandomBytes(256)); var gb = BigInteger.ValueOf((int)ServerDHInnerData["g"]).ModPow(b, new BigInteger(1, (byte[])ServerDHInnerData["dh_prime"])); gab = new BigInteger(1, (byte[])ServerDHInnerData["g_a"]).ModPow(b, new BigInteger(1, (byte[])ServerDHInnerData["dh_prime"])); TLObject ClientDHInnerData = schema.client_DH_inner_data(new { nonce = ServerDHInnerData["nonce"], server_nonce = ServerDHInnerData["server_nonce"], retry_id = 0L, g_b = gb.ToByteArrayUnsigned() }); var ClientDHInnerData_raw = ClientDHInnerData.Serialize(); byte[] ClientDHInnerDataHash = null; using (var memory = new MemoryStream()) using (var writer = new BinaryWriter(memory)) using (var sha = SHA1.Create()) { writer.Write(sha.ComputeHash(ClientDHInnerData_raw)); writer.Write(ClientDHInnerData_raw); ClientDHInnerDataHash = memory.ToArray(); } Logger.Log(Logger.Level.Debug, $"Sending ClientDHRequest"); // Get ready to the next response CurrentState = AuthenticationState.ClientDHRequest; MTSender.Send(schema.set_client_DH_params(new { nonce = ServerDHInnerData["nonce"], server_nonce = ServerDHInnerData["server_nonce"], encrypted_data = AES.EncryptAES(key, ClientDHInnerDataHash) })); break; case AuthenticationState.ClientDHRequest: // Make sure we have all the needed info if (gab == null) { var sad = new Exception("Unable to find the GAB object from previous steps. Please restart the connection process"); Logger.Log(sad); Response.TrySetException(sad); MTSender.TLObjectReceivedEvent -= Sender_TLObjectReceivedEvent; CurrentState = AuthenticationState.NotStarted; Logger.Log(Logger.Level.Debug, $"Unsubscribed from {nameof(MTSender.TLObjectReceivedEvent)} event"); Logger.Log(Logger.Level.Info, $"Auth aborted."); return; } else if (TimeOffset == null) { var sad = new Exception("Unable to find the TimeOffset from previous steps. Please restart the connection process"); Logger.Log(sad); Response.TrySetException(sad); MTSender.TLObjectReceivedEvent -= Sender_TLObjectReceivedEvent; CurrentState = AuthenticationState.NotStarted; Logger.Log(Logger.Level.Debug, $"Unsubscribed from {nameof(MTSender.TLObjectReceivedEvent)} event"); Logger.Log(Logger.Level.Info, $"Auth aborted."); return; } var SetClientDHParamsAnswer = e.TLObject; var AuthKey = new AuthKey(gab); var newNonceHashCalculated = AuthKey.CalcNewNonceHash((byte[])PQInnerData["new_nonce"], 1); Logger.Log(Logger.Level.Debug, $"Received TLObject {SetClientDHParamsAnswer["_"]}."); if (!((byte[])SetClientDHParamsAnswer["new_nonce_hash1"]).SequenceEqual(newNonceHashCalculated)) { var sad = new Exception("The server returned an invalid new nonce hash 1. Please restart the connection process"); Logger.Log(sad); Response.TrySetException(sad); MTSender.TLObjectReceivedEvent -= Sender_TLObjectReceivedEvent; CurrentState = AuthenticationState.NotStarted; Logger.Log(Logger.Level.Debug, $"Unsubscribed from {nameof(MTSender.TLObjectReceivedEvent)} event"); Logger.Log(Logger.Level.Info, $"Auth aborted."); return; } Logger.Log(Logger.Level.Info, $"Successfully negotiated authorization with the server"); MTSender.TLObjectReceivedEvent -= Sender_TLObjectReceivedEvent; Response.TrySetResult(new ServerAuthentication { AuthKey = AuthKey, TimeOffset = (int)TimeOffset }); break; } }