agent: xrcp implementation for connection via link (no multicast) (#884)

* WIP: start working on connection invites

startSession/OOB is broken now - the port isn't coming from the actualy assigned one.

* Add invite types

* clean old invite-related types

* apply renames

* Move SessionKeys from Invitation

* Stub host-side keys and handle

* move keys and handles to Types

* add Simplex.RemoteControl.Client

* more keys

* progress

* crypto for sessions

* progress to multicast

* multicast crypto

* add RC TLS server

* agent api for remote control

* WIP: tls client

* fix test

* update encoding to include nonce

* add TODO

* update

* Use network-info to find TransportHost

* request and submit tls client certificate

* WIP: add missing bits for testing RC client

* RCEncryptedHello encoding

* add block encoding

* refactor

* validate known host certificate

* remove some spaghetti

* functional API to host/ctrl clients

* refactor connectRCCtrl_

* refactor connectRCHost

* question

* add type

* fix RC session

* update doc

* update doc 2

* add block on confirmation

* remove unused parameter

* export CtrlSessKeys

* export

* fix parsing

* move test of xrcp handshake

* move KEM to HELLO step

* fix JSON

* type

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
This commit is contained in:
Alexander Bondarenko
2023-11-07 15:05:18 +02:00
committed by GitHub
parent 1a0c4b73de
commit 1a8dfb4cbe
22 changed files with 1181 additions and 316 deletions

66
tests/RemoteControl.hs Normal file
View File

@@ -0,0 +1,66 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE OverloadedStrings #-}
module RemoteControl where
import AgentTests.FunctionalAPITests (runRight_)
import Control.Logger.Simple
import Crypto.Random (drgNew)
import qualified Data.Aeson as J
import qualified Simplex.RemoteControl.Client as RC
import Test.Hspec
import UnliftIO
import UnliftIO.Concurrent
remoteControlTests :: Spec
remoteControlTests = do
describe "New controller/host pairing" $ do
it "should connect" testNewPairing
testNewPairing :: IO ()
testNewPairing = do
drg <- drgNew >>= newTVarIO
hp <- RC.newRCHostPairing
invVar <- newEmptyMVar
ctrl <- async . runRight_ $ do
logNote "c 1"
(inv, hc, r) <- RC.connectRCHost drg hp (J.String "app")
logNote "c 2"
putMVar invVar (inv, hc)
logNote "c 3"
Right (_sessId, r') <- atomically $ takeTMVar r
logNote "c 4"
Right (_rcHostSession, _rcHelloBody, _hp') <- atomically $ takeTMVar r'
logNote "c 5"
threadDelay 1000000
logNote "ctrl: ciao"
liftIO $ RC.cancelHostClient hc
(inv, hc) <- takeMVar invVar
-- logNote $ decodeUtf8 $ strEncode inv
host <- async . runRight_ $ do
logNote "h 1"
(rcCtrlClient, r) <- RC.connectRCCtrlURI drg inv Nothing (J.String "app")
logNote "h 2"
Right (_sessId', r') <- atomically $ takeTMVar r
logNote "h 3"
liftIO $ RC.confirmCtrlSession rcCtrlClient True
logNote "h 4"
Right (_rcCtrlSession, _rcCtrlPairing) <- atomically $ takeTMVar r'
logNote "h 5"
threadDelay 1000000
logNote "ctrl: adios"
timeout 10000000 (waitCatch ctrl) >>= \case
Just (Right ()) -> pure ()
err -> fail $ "Unexpected controller result: " <> show err
waitCatch hc.action >>= \case
Left err -> fromException err `shouldBe` Just AsyncCancelled
Right () -> fail "Unexpected controller finish"
timeout 10000000 (waitCatch host) >>= \case
Just (Right ()) -> pure ()
err -> fail $ "Unexpected host result: " <> show err