Compare commits
	
		
			4 Commits
		
	
	
		
			4b6bb780d4
			...
			15809f3fbd
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					15809f3fbd | ||
| 
						 | 
					f4c947e359 | ||
| 
						 | 
					5b31fef0c7 | ||
| 
						 | 
					a4ff706a28 | 
							
								
								
									
										46
									
								
								CryptographyService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								CryptographyService.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using Sodium;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace TeleTok
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class CryptographyService
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public string ToHexString(byte[] input)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var hexString = BitConverter.ToString(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            string result = hexString.Replace("-", "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return result.ToLower();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public byte[] GenerateLoginDigest()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            long now = DateTimeOffset.UtcNow.ToUnixTimeSeconds() * 1000;
 | 
				
			||||||
 | 
					            var message = $"login:{now / 1000 / (5 * 60)}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return GenericHash.Hash(message, (byte[]?) null, 32);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public KeyPair GenerateEd25519KeyPair(string seed)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            byte[] hash = GenericHash.Hash(seed, (byte[]?) null, 32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return PublicKeyAuth.GenerateKeyPair(hash);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string GenerateHexSignature(byte[] loginDigest, byte[] secretKey)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            byte[] signature = PublicKeyAuth.SignDetached(loginDigest, secretKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return ToHexString(signature);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string GenerateHexId(byte[] publicKey)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            byte[] hash = GenericHash.Hash(publicKey, null, publicKey.Length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return ToHexString(hash);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,14 +1,114 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Configuration;
 | 
					using System.Configuration;
 | 
				
			||||||
using Matrix.Sdk;
 | 
					using Matrix.Sdk;
 | 
				
			||||||
 | 
					using Matrix.Sdk.Core.Domain.MatrixRoom;
 | 
				
			||||||
 | 
					using Matrix.Sdk.Core.Domain.RoomEvent;
 | 
				
			||||||
 | 
					using Matrix.Sdk.Core.Infrastructure.Dto.Room.Create;
 | 
				
			||||||
 | 
					using Sodium;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace TeleTok
 | 
					namespace TeleTok
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public class MatrixListener
 | 
					    public class MatrixListener
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public void RunListener()
 | 
					        private static readonly CryptographyService CryptographyService = new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public record LoginRequest(Uri BaseAddress, string Username, string Password, string DeviceId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task RunListener()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            var factory = new MatrixClientFactory();
 | 
				
			||||||
 | 
					            var anotherFactory = new MatrixClientFactory();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            IMatrixClient client = factory.Create();
 | 
				
			||||||
 | 
					            IMatrixClient anotherClient = anotherFactory.Create();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            client.OnMatrixRoomEventsReceived += (sender, eventArgs) =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                foreach (BaseRoomEvent roomEvent in eventArgs.MatrixRoomEvents)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (roomEvent is not TextMessageEvent textMessageEvent)
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    (string roomId, string senderUserId, string message) = textMessageEvent;
 | 
				
			||||||
 | 
					                    if (client.UserId != senderUserId)
 | 
				
			||||||
 | 
					                        TeleTok.LogMessage($"RoomId: {roomId} received message from {senderUserId}: {message}.");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            anotherClient.OnMatrixRoomEventsReceived += (sender, eventArgs) =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                foreach (BaseRoomEvent roomEvent in eventArgs.MatrixRoomEvents)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if (roomEvent is not TextMessageEvent textMessageEvent)
 | 
				
			||||||
 | 
					                        continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    (string roomId, string senderUserId, string message) = textMessageEvent;
 | 
				
			||||||
 | 
					                    if (anotherClient.UserId != senderUserId)
 | 
				
			||||||
 | 
					                        TeleTok.LogMessage($"RoomId: {roomId} received message from {senderUserId}: {message}.");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            (Uri matrixNodeAddress, string username, string password, string deviceId) = CreateLoginRequest();
 | 
				
			||||||
 | 
					            await client.LoginAsync(matrixNodeAddress, username, password, deviceId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            LoginRequest request2 = CreateLoginRequest();
 | 
				
			||||||
 | 
					            await anotherClient.LoginAsync(request2.BaseAddress, request2.Username, request2.Password, request2.DeviceId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(client.IsLoggedIn)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                TeleTok.LogMessage($"client.IsLoggedIn: {client.IsLoggedIn}");
 | 
				
			||||||
 | 
					                TeleTok.LogMessage($"client.IsSyncing: {client.IsSyncing}");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            client.Start();
 | 
				
			||||||
 | 
					            anotherClient.Start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            CreateRoomResponse createRoomResponse = await client.CreateTrustedPrivateRoomAsync(new[]
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                anotherClient.UserId
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await anotherClient.JoinTrustedPrivateRoomAsync(createRoomResponse.RoomId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var spin = new SpinWait();
 | 
				
			||||||
 | 
					            while(anotherClient.JoinedRooms.Length ==0)
 | 
				
			||||||
 | 
					                spin.SpinOnce();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await client.SendMessageAsync(createRoomResponse.RoomId, "Hello");
 | 
				
			||||||
 | 
					            await anotherClient.SendMessageAsync(anotherClient.JoinedRooms[0].Id, ", ");
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            await client.SendMessageAsync(createRoomResponse.RoomId, "World");
 | 
				
			||||||
 | 
					            await anotherClient.SendMessageAsync(anotherClient.JoinedRooms[0].Id, "!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            TeleTok.LogMessage($"client.IsLoggedIn: {client.IsLoggedIn}");
 | 
				
			||||||
 | 
					            TeleTok.LogMessage($"client.IsSyncing: {client.IsSyncing}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Console.ReadLine();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            client.Stop();
 | 
				
			||||||
 | 
					            anotherClient.Stop();
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            Console.WriteLine($"client.IsLoggedIn: {client.IsLoggedIn}");
 | 
				
			||||||
 | 
					            Console.WriteLine($"client.IsSyncing: {client.IsSyncing}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static LoginRequest CreateLoginRequest()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var seed = Guid.NewGuid().ToString();
 | 
				
			||||||
 | 
					            KeyPair keyPair = CryptographyService.GenerateEd25519KeyPair(seed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            byte[] loginDigest = CryptographyService.GenerateLoginDigest();
 | 
				
			||||||
 | 
					            string hexSignature = CryptographyService.GenerateHexSignature(loginDigest, keyPair.PrivateKey);
 | 
				
			||||||
 | 
					            string publicKeyHex = CryptographyService.ToHexString(keyPair.PublicKey);
 | 
				
			||||||
 | 
					            string hexId = CryptographyService.GenerateHexId(keyPair.PublicKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var password = $"ed:{hexSignature}:{publicKeyHex}";
 | 
				
			||||||
 | 
					            string deviceId = publicKeyHex;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            LoginRequest loginRequest = new LoginRequest(TeleTok.mAddress, TeleTok.mBotUser, TeleTok.mBotPass, deviceId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return loginRequest;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								Program.cs
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								Program.cs
									
									
									
									
									
								
							@@ -19,21 +19,23 @@ namespace TeleTok
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Matrix bot config
 | 
					        // Matrix bot config
 | 
				
			||||||
        public static string matrixAddress = config.GetSection("TeleTokConf:matrixAddress").Value;
 | 
					        public static string matrixAddress = config.GetSection("TeleTokConf:matrixAddress").Value;
 | 
				
			||||||
 | 
					        public static Uri mAddress;
 | 
				
			||||||
        public static string mBotUser = config.GetSection("TeleTokConf:mBotUser").Value;
 | 
					        public static string mBotUser = config.GetSection("TeleTokConf:mBotUser").Value;
 | 
				
			||||||
        public static string mBotPass = config.GetSection("TeleTokConf:mBotPass").Value;
 | 
					        public static string mBotPass = config.GetSection("TeleTokConf:mBotPass").Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static async Task Main(string[] args)
 | 
					        static async Task Main(string[] args)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            //Checks to see what mode to run the bot in
 | 
					            //Checks to see what mode to run the bot in
 | 
				
			||||||
 | 
					            LogMessage($"The current running config is: \n Bot Mode: {botMode} \n Telegram Token: {token} \n ProxiTok Instance: {ptInstance} \n Matrix Homeserver: {matrixAddress} \n Matrix Bot User: {mBotUser}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(botMode == "telegram")
 | 
					            if(botMode == "telegram")
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                //Checks if the config json data is valid
 | 
					                //Checks if the config json data is valid
 | 
				
			||||||
                if(ConfigCheck(token) == false)
 | 
					                if(!ConfigCheck(token))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    LogMessage("Telegram bot token is invalid! Exiting...");
 | 
					                    LogMessage("Telegram bot token is invalid! Exiting...");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if(ConfigCheck(ptInstance) == false)
 | 
					                else if(!ConfigCheck(ptInstance))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    LogMessage("Proxitok instance is invalid! Exiting...");
 | 
					                    LogMessage("Proxitok instance is invalid! Exiting...");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -48,15 +50,20 @@ namespace TeleTok
 | 
				
			|||||||
            else if(botMode == "matrix")
 | 
					            else if(botMode == "matrix")
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                //Checks if the config json data is valid
 | 
					                //Checks if the config json data is valid
 | 
				
			||||||
                if(ConfigCheck(matrixAddress) == false)
 | 
					                if(Uri.IsWellFormedUriString(matrixAddress, UriKind.Absolute))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    LogMessage("Synapse address is invalid! Exiting...");
 | 
					                    mAddress = new Uri(matrixAddress);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if(ConfigCheck(mBotUser) == false)
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    LogMessage("Matrix server address is not a valid URL! Exiting...");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(!ConfigCheck(mBotUser))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    LogMessage("Matrix bot username is invalid! Exiting...");
 | 
					                    LogMessage("Matrix bot username is invalid! Exiting...");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if(ConfigCheck(mBotPass) == false)
 | 
					                else if(!ConfigCheck(mBotPass))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    LogMessage("Matrix bot password is invalid! Exiting...");
 | 
					                    LogMessage("Matrix bot password is invalid! Exiting...");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -65,7 +72,7 @@ namespace TeleTok
 | 
				
			|||||||
                    MatrixListener mListener = new MatrixListener();
 | 
					                    MatrixListener mListener = new MatrixListener();
 | 
				
			||||||
                    LogMessage("Now listening...");
 | 
					                    LogMessage("Now listening...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    mListener.RunListener();
 | 
					                    await mListener.RunListener();
 | 
				
			||||||
                }              
 | 
					                }              
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@
 | 
				
			|||||||
    <PackageReference Include="Matrix.Sdk" Version="1.0.7" />
 | 
					    <PackageReference Include="Matrix.Sdk" Version="1.0.7" />
 | 
				
			||||||
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.2" />
 | 
					    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.2" />
 | 
				
			||||||
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
 | 
					    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
 | 
				
			||||||
 | 
					    <PackageReference Include="Sodium.Core" Version="1.3.3" />
 | 
				
			||||||
    <PackageReference Include="Telegram.Bot" Version="17.0.0" />
 | 
					    <PackageReference Include="Telegram.Bot" Version="17.0.0" />
 | 
				
			||||||
    <PackageReference Include="Telegram.Bot.Extensions.Polling" Version="1.0.2" />
 | 
					    <PackageReference Include="Telegram.Bot.Extensions.Polling" Version="1.0.2" />
 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user