Skip to content

Commit

Permalink
External commits: add additional checks (#2852)
Browse files Browse the repository at this point in the history
  • Loading branch information
smatting authored Nov 21, 2022
1 parent f9a0482 commit df49506
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 23 deletions.
1 change: 1 addition & 0 deletions changelog.d/5-internal/pr-2852
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
External commits: add additional checks
42 changes: 24 additions & 18 deletions services/galley/src/Galley/API/MLS/Message.hs
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,7 @@ processExternalCommit ::
ErrorS 'MLSClientSenderUserMismatch,
ErrorS 'MLSKeyPackageRefNotFound,
ErrorS 'MLSStaleMessage,
ErrorS 'MLSMissingSenderClient,
ExternalAccess,
FederatorAccess,
GundeckAccess,
Expand All @@ -668,14 +669,15 @@ processExternalCommit ::
]
r =>
Qualified UserId ->
Maybe ClientId ->
Local Data.Conversation ->
ClientMap ->
Epoch ->
GroupId ->
ProposalAction ->
Maybe UpdatePath ->
Sem r ()
processExternalCommit qusr lconv cm epoch groupId action updatePath = withCommitLock groupId epoch $ do
processExternalCommit qusr mSenderClient lconv cm epoch groupId action updatePath = withCommitLock groupId epoch $ do
newKeyPackage <-
upLeaf
<$> note
Expand All @@ -688,13 +690,30 @@ processExternalCommit qusr lconv cm epoch groupId action updatePath = withCommit
throw . mlsProtocolError $
"The external commit must not have add proposals"

cid <- case kpIdentity (rmValue newKeyPackage) of
Left e -> throw (mlsProtocolError $ "Failed to parse the client identity: " <> e)
Right v -> pure v
newRef <-
kpRef' newKeyPackage
& note (mlsProtocolError "An invalid key package in the update path")

-- validate and update mapping in brig
mCid <-
nkpresClientIdentity
<$$> validateAndAddKeyPackageRef
NewKeyPackage
{ nkpConversation = Data.convId <$> qUntagged lconv,
nkpKeyPackage = KeyPackageData (rmRaw newKeyPackage)
}
cid <- mCid & note (mlsProtocolError "Tried to add invalid KeyPackage")

unless (cidQualifiedUser cid == qusr) $
throw . mlsProtocolError $
"The external commit attempts to add another user"

senderClient <- noteS @'MLSMissingSenderClient mSenderClient

unless (ciClient cid == senderClient) $
throw . mlsProtocolError $
"The external commit attempts to add another client of the user, it must only add itself"

-- check if there is a key package ref in the remove proposal
remRef <-
if Map.null (paRemove action)
Expand All @@ -707,21 +726,8 @@ processExternalCommit qusr lconv cm epoch groupId action updatePath = withCommit
$ "The external commit attempts to remove a client from a user other than themselves"
pure (Just r)

-- first perform checks and map the key package if valid
addKeyPackageRef
newRef
(cidQualifiedUser cid)
(ciClient cid)
(Data.convId <$> qUntagged lconv)
-- now it is safe to update the mapping without further checks
-- FUTUREWORK: This call is redundent and reduces to the previous
-- call of addKeyPackageRef when remRef is Nothing! Should be
-- limited to cases where remRef is not Nothing.
updateKeyPackageMapping lconv qusr (ciClient cid) remRef newRef

-- FUTUREWORK: Resubmit backend-provided proposals when processing an
-- external commit.

-- increment epoch number
setConversationEpoch (Data.convId (tUnqualified lconv)) (succ epoch)
-- fetch local conversation with new epoch
Expand Down Expand Up @@ -782,7 +788,7 @@ processCommitWithAction ::
processCommitWithAction qusr senderClient con lconv cm epoch groupId action sender commit =
case sender of
MemberSender ref -> processInternalCommit qusr senderClient con lconv cm epoch groupId action ref commit
NewMemberSender -> processExternalCommit qusr lconv cm epoch groupId action (cPath commit) $> []
NewMemberSender -> processExternalCommit qusr senderClient lconv cm epoch groupId action (cPath commit) $> []
_ -> throw (mlsProtocolError "Unexpected sender")

processInternalCommit ::
Expand Down
4 changes: 2 additions & 2 deletions services/galley/test/integration/API/MLS.hs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ testAddUserWithBundleIncompleteWelcome = do
bundle <- createBundle commit
err <-
responseJsonError
=<< postCommitBundle (ciUser (mpSender commit)) bundle
=<< postCommitBundle (mpSender commit) bundle
<!! const 400 === statusCode
liftIO $ Wai.label err @?= "mls-welcome-mismatch"

Expand Down Expand Up @@ -987,7 +987,7 @@ testExternalCommitNotMember = do
<$> getGroupInfo (ciUser alice1) qcnv
mp <- createExternalCommit bob1 (Just pgs) qcnv
bundle <- createBundle mp
postCommitBundle (ciUser (mpSender mp)) bundle
postCommitBundle (mpSender mp) bundle
!!! const 404 === statusCode

testExternalCommitSameClient :: TestM ()
Expand Down
7 changes: 4 additions & 3 deletions services/galley/test/integration/API/MLS/Util.hs
Original file line number Diff line number Diff line change
Expand Up @@ -130,15 +130,16 @@ postCommitBundle ::
MonadHttp m,
HasGalley m
) =>
UserId ->
ClientIdentity ->
ByteString ->
m ResponseLBS
postCommitBundle sender bundle = do
galley <- viewGalley
post
( galley
. paths ["mls", "commit-bundles"]
. zUser sender
. zUser (ciUser sender)
. zClient (ciClient sender)
. zConn "conn"
. content "application/x-protobuf"
. bytes bundle
Expand Down Expand Up @@ -888,7 +889,7 @@ sendAndConsumeCommitBundle mp = do
events <-
fmap mmssEvents
. responseJsonError
=<< postCommitBundle (ciUser (mpSender mp)) bundle
=<< postCommitBundle (mpSender mp) bundle
<!! const 201 === statusCode
consumeMessage mp
traverse_ consumeWelcome (mpWelcome mp)
Expand Down

0 comments on commit df49506

Please sign in to comment.