From eab5ac045546f65083f0ac1148b602e65fb72f49 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Sat, 16 Aug 2025 20:21:40 +0100 Subject: [PATCH] agent client (WIP) --- src/Simplex/Messaging/Agent/Client.hs | 4 +-- src/Simplex/Messaging/Agent/Store.hs | 21 +++++++++++++++ .../Messaging/Agent/Store/AgentStore.hs | 27 +++++++++++++++++++ .../Migrations/M20250815_service_certs.hs | 16 +++++------ 4 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/Simplex/Messaging/Agent/Client.hs b/src/Simplex/Messaging/Agent/Client.hs index b928815db..4362de3c0 100644 --- a/src/Simplex/Messaging/Agent/Client.hs +++ b/src/Simplex/Messaging/Agent/Client.hs @@ -484,7 +484,7 @@ data UserNetworkType = UNNone | UNCellular | UNWifi | UNEthernet | UNOther -- | Creates an SMP agent client instance that receives commands and sends responses via 'TBQueue's. newAgentClient :: Int -> InitialAgentServers -> UTCTime -> Env -> IO AgentClient -newAgentClient clientId InitialAgentServers {smp, ntf, xftp, netCfg, presetDomains} currentTs agentEnv = do +newAgentClient clientId InitialAgentServers {smp, ntf, xftp, netCfg, useServices, presetDomains} currentTs agentEnv = do let cfg = config agentEnv qSize = tbqSize cfg proxySessTs <- newTVarIO =<< getCurrentTime @@ -494,7 +494,7 @@ newAgentClient clientId InitialAgentServers {smp, ntf, xftp, netCfg, presetDomai msgQ <- newTBQueueIO qSize smpServers <- newTVarIO $ M.map mkUserServers smp smpClients <- TM.emptyIO - smpServiceCreds <- TM.emptyIO + smpServiceCreds <- newTVarIO =<< mapM (\enable -> if enable then Just <$> TM.emptyIO else pure Nothing) useServices smpProxiedRelays <- TM.emptyIO ntfServers <- newTVarIO ntf ntfClients <- TM.emptyIO diff --git a/src/Simplex/Messaging/Agent/Store.hs b/src/Simplex/Messaging/Agent/Store.hs index 7eab3fbbd..a1130d561 100644 --- a/src/Simplex/Messaging/Agent/Store.hs +++ b/src/Simplex/Messaging/Agent/Store.hs @@ -27,6 +27,8 @@ import qualified Data.List.NonEmpty as L import Data.Maybe (isJust) import Data.Time (UTCTime) import Data.Type.Equality +import qualified Data.X509.Validation as XV +import qualified Network.TLS as TLS import Simplex.Messaging.Agent.Protocol import Simplex.Messaging.Agent.RetryInterval (RI2State) import Simplex.Messaging.Agent.Store.Common @@ -157,6 +159,25 @@ data InvShortLink = InvShortLink } deriving (Show) +data ClientService = ClientService + { clientServiceId :: Int64, + userId :: UserId, + server :: SMPServer, + credential :: TLS.Credential, + certHash :: XV.Fingerprint, + rcvServiceId :: Maybe SMP.ServiceId + } +-- client_services( +-- client_service_id INTEGER PRIMARY KEY AUTOINCREMENT, +-- user_id INTEGER NOT NULL REFERENCES users ON UPDATE RESTRICT ON DELETE CASCADE, +-- host TEXT NOT NULL, +-- port TEXT NOT NULL, +-- service_cert BLOB NOT NULL, +-- service_priv_key BLOB NOT NULL, +-- rcv_service_id BLOB, +-- FOREIGN KEY(host, port) REFERENCES servers ON UPDATE CASCADE ON DELETE RESTRICT, +-- ); + type SndQueue = StoredSndQueue 'DBStored type NewSndQueue = StoredSndQueue 'DBNew diff --git a/src/Simplex/Messaging/Agent/Store/AgentStore.hs b/src/Simplex/Messaging/Agent/Store/AgentStore.hs index 577bd1249..a2e1c2214 100644 --- a/src/Simplex/Messaging/Agent/Store/AgentStore.hs +++ b/src/Simplex/Messaging/Agent/Store/AgentStore.hs @@ -34,6 +34,11 @@ module Simplex.Messaging.Agent.Store.AgentStore deleteUsersWithoutConns, checkUser, + -- * Client services + getCreateClientService, + setClientServiceId, + deleteClientService, + -- * Queues and connections createNewConn, updateNewConnRcv, @@ -261,6 +266,7 @@ import Data.Text.Encoding (decodeLatin1, encodeUtf8) import Data.Time.Clock (NominalDiffTime, UTCTime, addUTCTime, getCurrentTime) import Data.Word (Word32) import Network.Socket (ServiceName) +import qualified Network.TLS as TLS import Simplex.FileTransfer.Client (XFTPChunkSpec (..)) import Simplex.FileTransfer.Description import Simplex.FileTransfer.Protocol (FileParty (..), SFileParty (..)) @@ -368,6 +374,27 @@ deleteUsersWithoutConns db = do forM_ userIds $ DB.execute db "DELETE FROM users WHERE user_id = ?" . Only pure userIds +-- TODO [certs rcv] +getCreateClientService :: DB.Connection -> UserId -> SMPServer -> TLS.Credential -> IO (Either StoreError ClientService) +getCreateClientService = undefined + +setClientServiceId :: DB.Connection -> ClientService -> ServiceId -> IO (Either StoreError ()) +setClientServiceId = undefined + +deleteClientService :: DB.Connection -> ClientService -> IO (Either StoreError ()) +deleteClientService = undefined + +-- client_services( +-- client_service_id INTEGER PRIMARY KEY AUTOINCREMENT, +-- user_id INTEGER NOT NULL REFERENCES users ON UPDATE RESTRICT ON DELETE CASCADE, +-- host TEXT NOT NULL, +-- port TEXT NOT NULL, +-- service_cert BLOB NOT NULL, +-- service_priv_key BLOB NOT NULL, +-- rcv_service_id BLOB, +-- FOREIGN KEY(host, port) REFERENCES servers ON UPDATE CASCADE ON DELETE RESTRICT, +-- ); + createConn_ :: TVar ChaChaDRG -> ConnData -> diff --git a/src/Simplex/Messaging/Agent/Store/SQLite/Migrations/M20250815_service_certs.hs b/src/Simplex/Messaging/Agent/Store/SQLite/Migrations/M20250815_service_certs.hs index a4ffb5a3a..1c50d0fcf 100644 --- a/src/Simplex/Messaging/Agent/Store/SQLite/Migrations/M20250815_service_certs.hs +++ b/src/Simplex/Messaging/Agent/Store/SQLite/Migrations/M20250815_service_certs.hs @@ -9,20 +9,20 @@ import Database.SQLite.Simple.QQ (sql) m20250815_service_certs :: Query m20250815_service_certs = [sql| -CREATE TABLE server_certs( - server_cert_id INTEGER PRIMARY KEY AUTOINCREMENT, +CREATE TABLE client_services( + client_service_id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL REFERENCES users ON UPDATE RESTRICT ON DELETE CASCADE, host TEXT NOT NULL, port TEXT NOT NULL, - certificate BLOB NOT NULL, - priv_key BLOB NOT NULL, - service_id BLOB, + service_cert BLOB NOT NULL, + service_priv_key BLOB NOT NULL, + rcv_service_id BLOB, FOREIGN KEY(host, port) REFERENCES servers ON UPDATE CASCADE ON DELETE RESTRICT, ); -CREATE UNIQUE INDEX idx_server_certs_user_id_host_port ON server_certs(user_id, host, port); +CREATE UNIQUE INDEX idx_server_certs_user_id_host_port ON client_services(user_id, host, port); -CREATE INDEX idx_server_certs_host_port ON server_certs(host, port); +CREATE INDEX idx_server_certs_host_port ON client_services(host, port); ALTER TABLE rcv_queues ADD COLUMN rcv_service_assoc INTEGER NOT NULL DEFAULT 0; |] @@ -36,5 +36,5 @@ DROP INDEX idx_server_certs_host_port; DROP INDEX idx_server_certs_user_id_host_port; -DROP TABLE server_certs; +DROP TABLE client_services; |]