Compare commits
8 Commits
main
...
feature/ma
Author | SHA1 | Date | |
---|---|---|---|
|
15809f3fbd | ||
|
f4c947e359 | ||
|
5b31fef0c7 | ||
|
a4ff706a28 | ||
|
4b6bb780d4 | ||
|
e8463ecc25 | ||
|
2083e8279f | ||
|
19e011dfac |
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
114
MatrixListener.cs
Normal file
114
MatrixListener.cs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
using System;
|
||||||
|
using System.Configuration;
|
||||||
|
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
|
||||||
|
{
|
||||||
|
public class MatrixListener
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
85
Program.cs
85
Program.cs
@ -10,27 +10,92 @@ namespace TeleTok
|
|||||||
.AddJsonFile("config.json", true)
|
.AddJsonFile("config.json", true)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
// Value to see what bot mode to run in
|
||||||
|
public static string botMode = config.GetSection("TeleTokConf:botMode").Value;
|
||||||
|
|
||||||
|
// Telegram bot config
|
||||||
public static string token = config.GetSection("TeleTokConf:token").Value;
|
public static string token = config.GetSection("TeleTokConf:token").Value;
|
||||||
public static string ptInstance = config.GetSection("TeleTokConf:proxitokInstance").Value;
|
public static string ptInstance = config.GetSection("TeleTokConf:ptInstance").Value;
|
||||||
|
|
||||||
|
// Matrix bot config
|
||||||
|
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 mBotPass = config.GetSection("TeleTokConf:mBotPass").Value;
|
||||||
|
|
||||||
static async Task Main(string[] args)
|
static async Task Main(string[] args)
|
||||||
{
|
{
|
||||||
//Checks if the config json data is valid
|
//Checks to see what mode to run the bot in
|
||||||
if(token == "" || token == null || token == "INSERT TOKEN HERE")
|
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")
|
||||||
{
|
{
|
||||||
LogMessage("Telegram bot token is invalid! Exiting...");
|
//Checks if the config json data is valid
|
||||||
|
if(!ConfigCheck(token))
|
||||||
|
{
|
||||||
|
LogMessage("Telegram bot token is invalid! Exiting...");
|
||||||
|
}
|
||||||
|
else if(!ConfigCheck(ptInstance))
|
||||||
|
{
|
||||||
|
LogMessage("Proxitok instance is invalid! Exiting...");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TelegramListener tListener = new TelegramListener();
|
||||||
|
LogMessage("Now listening...");
|
||||||
|
|
||||||
|
tListener.RunListener();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(ptInstance == "" || ptInstance == null || ptInstance == "PROXITOK INSTANCE URL")
|
else if(botMode == "matrix")
|
||||||
{
|
{
|
||||||
LogMessage("Proxitok instance is invalid! Exiting...");
|
//Checks if the config json data is valid
|
||||||
|
if(Uri.IsWellFormedUriString(matrixAddress, UriKind.Absolute))
|
||||||
|
{
|
||||||
|
mAddress = new Uri(matrixAddress);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogMessage("Matrix server address is not a valid URL! Exiting...");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ConfigCheck(mBotUser))
|
||||||
|
{
|
||||||
|
LogMessage("Matrix bot username is invalid! Exiting...");
|
||||||
|
}
|
||||||
|
else if(!ConfigCheck(mBotPass))
|
||||||
|
{
|
||||||
|
LogMessage("Matrix bot password is invalid! Exiting...");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MatrixListener mListener = new MatrixListener();
|
||||||
|
LogMessage("Now listening...");
|
||||||
|
|
||||||
|
await mListener.RunListener();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TelegramListener listener = new TelegramListener();
|
LogMessage("Bot mode is not configured! Enter either \'telegram\' or \'matrix\'");
|
||||||
LogMessage("Now listening...");
|
}
|
||||||
|
}
|
||||||
|
|
||||||
listener.RunListener();
|
public static bool ConfigCheck(string confItem)
|
||||||
}
|
{
|
||||||
|
if(confItem == "" || confItem == null
|
||||||
|
|| confItem == "INSERT TOKEN HERE"
|
||||||
|
|| confItem == "PROXITOK INSTANCE URL"
|
||||||
|
|| confItem == "SYNAPSE SERVER URL"
|
||||||
|
|| confItem == "MATRIX BOT USERNAMEL"
|
||||||
|
|| confItem == "MATRIX BOT PASSWORD")
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LogMessage(string text)
|
public static void LogMessage(string text)
|
||||||
|
@ -8,8 +8,10 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<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>
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"TeleTokConf": {
|
"TeleTokConf": {
|
||||||
|
"botMode": "telegram",
|
||||||
"token": "INSERT TOKEN HERE",
|
"token": "INSERT TOKEN HERE",
|
||||||
"proxitokInstance": "PROXITOK INSTANCE URL"
|
"ptInstance": "PROXITOK INSTANCE URL",
|
||||||
|
"matrixAddress": "SYNAPSE SERVER URL",
|
||||||
|
"mBotUser": "MATRIX BOT USERNAME",
|
||||||
|
"mBotPass": "MATRIX BOT PASSWORD"
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user