aboutsummaryrefslogtreecommitdiff
path: root/Assistant/Threads/PairListener.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2012-09-11 03:16:00 -0400
committerGravatar Joey Hess <joey@kitenet.net>2012-09-11 03:16:00 -0400
commit0208d6aa82c12600ecca5502357aa36ad928478d (patch)
tree6a9d81568b239fbeb78592ec9d728c580c62182d /Assistant/Threads/PairListener.hs
parentb3f4c6eb683ebedf0e73bbca8305bb3f97cac6f1 (diff)
add a UUID to pair requests
Pair requests the the same UUID are part of the same pairing session, which allows us to detect attempts to brute force the shared secret, as that will result in pair requests with the same UUID that are not verified with the right secret.
Diffstat (limited to 'Assistant/Threads/PairListener.hs')
-rw-r--r--Assistant/Threads/PairListener.hs29
1 files changed, 22 insertions, 7 deletions
diff --git a/Assistant/Threads/PairListener.hs b/Assistant/Threads/PairListener.hs
index 7ba673ec2..09fd9513d 100644
--- a/Assistant/Threads/PairListener.hs
+++ b/Assistant/Threads/PairListener.hs
@@ -36,8 +36,8 @@ pairListenerThread st dstatus scanremotes urlrenderer = thread $ withSocketsDo $
go sock cache = getmsg sock [] >>= \msg -> case readish msg of
Nothing -> go sock cache
Just m -> do
- pip <- pairingInProgress <$> getDaemonStatus dstatus
- let verified = maybe False (verifiedPairMsg m) pip
+ (pip, verified) <- verificationCheck m
+ =<< (pairingInProgress <$> getDaemonStatus dstatus)
case pairMsgStage m of
PairReq -> do
pairReqReceived verified dstatus urlrenderer m
@@ -49,6 +49,23 @@ pairListenerThread st dstatus scanremotes urlrenderer = thread $ withSocketsDo $
pairDoneReceived verified pip st dstatus scanremotes m
go sock cache
+ {- As well as verifying the message using the shared secret,
+ - check its UUID against the UUID we have stored. If
+ - they're the same, someone is sending bogus messages,
+ - which could be an attempt to brute force the shared
+ - secret. -}
+ verificationCheck m (Just pip) = do
+ let verified = verifiedPairMsg m pip
+ let sameuuid = pairUUID (inProgressPairData pip) == pairUUID (pairMsgData $ m)
+ if (not verified && sameuuid)
+ then do
+ runThreadState st $
+ warning "detected possible pairing brute force attempt; disabled pairing"
+ stopSending dstatus pip
+ return (Nothing, False)
+ else return (Just pip, verified && sameuuid)
+ verificationCheck _ Nothing = return (Nothing, False)
+
{- PairReqs invalidate the cache of recently finished pairings.
- This is so that, if a new pairing is started with the
- same secret used before, a bogus PairDone is not sent. -}
@@ -125,12 +142,10 @@ pairAckReceived _ _ _ dstatus _ msg cache = do
{- If we get a verified PairDone, the host has accepted our PairAck, and
- has paired with us. Stop sending PairAcks, and finish pairing with them.
-
- - If we get an unverified PairDone that matches the PairReq
- TODO: Should third-party hosts remove their pair request alert when they
- - see a PairDone? How to tell if a PairDone matches with the PairReq
- - that brought up the alert? Cannot verify it without the secret..
- - Also, the user could have already clicked on the alert and be entering
- - the secret. Would be better to start a fresh pair request in this
+ - see a PairDone?
+ - Complication: The user could have already clicked on the alert and be
+ - entering the secret. Would be better to start a fresh pair request in this
- situation.
-}
pairDoneReceived :: Bool -> Maybe PairingInProgress -> ThreadState -> DaemonStatusHandle -> ScanRemoteMap -> PairMsg -> IO ()