diff options
author | joe <joe@jerkface.net> | 2017-10-19 22:00:34 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-10-19 22:00:34 -0400 |
commit | 987915fb21ac824bfb8fc49c5cceb3aa0f1440c2 (patch) | |
tree | 74fb04e5248f6fa7486216ec5dd1c9ea1258873d /src/Network/Tox/Onion | |
parent | 27dfb777280028b5ca6dad44f481783d8bab602e (diff) |
Successful toxid announce.
Diffstat (limited to 'src/Network/Tox/Onion')
-rw-r--r-- | src/Network/Tox/Onion/Handlers.hs | 23 | ||||
-rw-r--r-- | src/Network/Tox/Onion/Transport.hs | 85 |
2 files changed, 59 insertions, 49 deletions
diff --git a/src/Network/Tox/Onion/Handlers.hs b/src/Network/Tox/Onion/Handlers.hs index 9702cbb8..047b902d 100644 --- a/src/Network/Tox/Onion/Handlers.hs +++ b/src/Network/Tox/Onion/Handlers.hs | |||
@@ -79,9 +79,15 @@ announceH routing toks keydb oaddr req = do | |||
79 | let naddr = onionNodeInfo oaddr | 79 | let naddr = onionNodeInfo oaddr |
80 | ns <- getNodesH routing naddr (GetNodes (announceSeeking req)) | 80 | ns <- getNodesH routing naddr (GetNodes (announceSeeking req)) |
81 | tm <- getPOSIXTime | 81 | tm <- getPOSIXTime |
82 | |||
82 | let storing = case oaddr of | 83 | let storing = case oaddr of |
83 | OnionToOwner _ pth -> guard (nodeId naddr == announceSeeking req) >> Just pth | 84 | OnionToOwner _ pth -> guard (nodeId naddr == announceSeeking req) >> Just pth |
84 | _ -> Nothing | 85 | _ -> Nothing |
86 | hPutStrLn stderr $ unlines [ "announceH: nodeId = " ++ show (nodeId naddr) | ||
87 | , " announceSeeking = " ++ show (announceSeeking req) | ||
88 | , " withTok = " ++ show withTok | ||
89 | , " storing = " ++ maybe "False" (const "True") storing | ||
90 | ] | ||
85 | record <- atomically $ do | 91 | record <- atomically $ do |
86 | forM_ storing $ \retpath -> when withTok $ do | 92 | forM_ storing $ \retpath -> when withTok $ do |
87 | let toxpath = AnnouncedRoute naddr{ nodeId = announceKey req } retpath | 93 | let toxpath = AnnouncedRoute naddr{ nodeId = announceKey req } retpath |
@@ -186,7 +192,7 @@ announceSerializer getTimeout = MethodSerializer | |||
186 | { -- The public key is our real long term public key if we want to | 192 | { -- The public key is our real long term public key if we want to |
187 | -- announce ourselves, a temporary one if we are searching for | 193 | -- announce ourselves, a temporary one if we are searching for |
188 | -- friends. | 194 | -- friends. |
189 | senderKey = fromJust $ onionKey src -- TODO: FIXME: this should be a temporary alias key | 195 | senderKey = onionKey src |
190 | , assymNonce = n24 | 196 | , assymNonce = n24 |
191 | , assymData = Identity (req, n8) | 197 | , assymData = Identity (req, n8) |
192 | } | 198 | } |
@@ -224,16 +230,15 @@ unwrapAnnounceResponse ni (AnnounceResponse is_stored (SendNodes ns)) | |||
224 | sendOnion :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) | 230 | sendOnion :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) |
225 | -> Client r | 231 | -> Client r |
226 | -> AnnounceRequest | 232 | -> AnnounceRequest |
227 | -> NodeInfo | 233 | -> OnionDestination r |
228 | -> (NodeInfo -> AnnounceResponse -> t) | 234 | -> (NodeInfo -> AnnounceResponse -> t) |
229 | -> IO (Maybe t) | 235 | -> IO (Maybe t) |
230 | sendOnion getTimeout client req ni unwrap = | 236 | sendOnion getTimeout client req oaddr unwrap = |
231 | -- Four tries and then we tap out. | 237 | -- Four tries and then we tap out. |
232 | flip fix 4 $ \loop n -> do | 238 | flip fix 4 $ \loop n -> do |
233 | let oaddr = OnionDestination ni Nothing | ||
234 | mb <- QR.sendQuery client (announceSerializer getTimeout) req oaddr | 239 | mb <- QR.sendQuery client (announceSerializer getTimeout) req oaddr |
235 | maybe (if n>0 then loop $! n - 1 else return Nothing) | 240 | maybe (if n>0 then loop $! n - 1 else return Nothing) |
236 | (return . Just . unwrap ni) | 241 | (return . Just . unwrap (onionNodeInfo oaddr)) |
237 | $ join mb | 242 | $ join mb |
238 | 243 | ||
239 | getRendezvous :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) | 244 | getRendezvous :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) |
@@ -241,8 +246,9 @@ getRendezvous :: (TransactionId -> OnionDestination r -> STM (OnionDestination r | |||
241 | -> NodeId | 246 | -> NodeId |
242 | -> NodeInfo | 247 | -> NodeInfo |
243 | -> IO (Maybe ([NodeInfo],[Rendezvous],Maybe Nonce32)) | 248 | -> IO (Maybe ([NodeInfo],[Rendezvous],Maybe Nonce32)) |
244 | getRendezvous getTimeout client nid ni = | 249 | getRendezvous getTimeout client nid ni = do |
245 | sendOnion getTimeout client (AnnounceRequest zeros32 nid zeroID) ni unwrapAnnounceResponse | 250 | let oaddr = OnionDestination SearchingAlias ni Nothing |
251 | sendOnion getTimeout client (AnnounceRequest zeros32 nid zeroID) oaddr unwrapAnnounceResponse | ||
246 | 252 | ||
247 | putRendezvous :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) | 253 | putRendezvous :: (TransactionId -> OnionDestination r -> STM (OnionDestination r, Int)) |
248 | -> TransportCrypto | 254 | -> TransportCrypto |
@@ -255,5 +261,6 @@ putRendezvous getTimeout crypto client pubkey nonce32 ni = do | |||
255 | let longTermKey = key2id pubkey | 261 | let longTermKey = key2id pubkey |
256 | rkey = rendezvousPublic crypto | 262 | rkey = rendezvousPublic crypto |
257 | rendezvousKey = key2id rkey | 263 | rendezvousKey = key2id rkey |
258 | sendOnion getTimeout client (AnnounceRequest nonce32 longTermKey rendezvousKey) ni | 264 | let oaddr = OnionDestination (AnnouncingAlias longTermKey) ni Nothing |
265 | sendOnion getTimeout client (AnnounceRequest nonce32 longTermKey rendezvousKey) oaddr | ||
259 | $ \ni resp -> (Rendezvous rkey ni, resp) | 266 | $ \ni resp -> (Rendezvous rkey ni, resp) |
diff --git a/src/Network/Tox/Onion/Transport.hs b/src/Network/Tox/Onion/Transport.hs index 34ba23f6..e52c8faa 100644 --- a/src/Network/Tox/Onion/Transport.hs +++ b/src/Network/Tox/Onion/Transport.hs | |||
@@ -20,6 +20,7 @@ module Network.Tox.Onion.Transport | |||
20 | , parseDataToRoute | 20 | , parseDataToRoute |
21 | , encodeDataToRoute | 21 | , encodeDataToRoute |
22 | , forwardOnions | 22 | , forwardOnions |
23 | , AliasSelector(..) | ||
23 | , OnionDestination(..) | 24 | , OnionDestination(..) |
24 | , OnionMessage(..) | 25 | , OnionMessage(..) |
25 | , Rendezvous(..) | 26 | , Rendezvous(..) |
@@ -39,7 +40,7 @@ module Network.Tox.Onion.Transport | |||
39 | , OnionRoute(..) | 40 | , OnionRoute(..) |
40 | , N3 | 41 | , N3 |
41 | , onionKey | 42 | , onionKey |
42 | , onionNodeInfo | 43 | , onionAliasSelector |
43 | ) where | 44 | ) where |
44 | 45 | ||
45 | import Network.Address (fromSockAddr,toSockAddr,setPort,either4or6,sockAddrPort) | 46 | import Network.Address (fromSockAddr,toSockAddr,setPort,either4or6,sockAddrPort) |
@@ -100,17 +101,27 @@ msgNonce (OnionAnnounceResponse _ n24 _) = n24 | |||
100 | msgNonce (OnionToRoute _ a) = assymNonce a | 101 | msgNonce (OnionToRoute _ a) = assymNonce a |
101 | msgNonce (OnionToRouteResponse a) = assymNonce a | 102 | msgNonce (OnionToRouteResponse a) = assymNonce a |
102 | 103 | ||
104 | data AliasSelector = SearchingAlias | AnnouncingAlias NodeId | ||
105 | deriving (Eq,Ord,Show) | ||
106 | |||
103 | data OnionDestination r | 107 | data OnionDestination r |
104 | = OnionToOwner NodeInfo (ReturnPath N3) -- ^ Somebody else's path to us. | 108 | = OnionToOwner |
105 | | OnionDestination NodeInfo (Maybe r) -- ^ Our own onion-path. | 109 | { onionNodeInfo :: NodeInfo |
110 | , onionReturnPath :: ReturnPath N3 -- ^ Somebody else's path to us. | ||
111 | } | ||
112 | | OnionDestination | ||
113 | { onionAliasSelector' :: AliasSelector | ||
114 | , onionNodeInfo :: NodeInfo | ||
115 | , onionRouteSpec :: Maybe r -- ^ Our own onion-path. | ||
116 | } | ||
106 | deriving Show | 117 | deriving Show |
107 | 118 | ||
108 | onionNodeInfo :: OnionDestination r -> NodeInfo | 119 | onionAliasSelector :: OnionDestination r -> AliasSelector |
109 | onionNodeInfo (OnionToOwner ni _) = ni | 120 | onionAliasSelector (OnionToOwner {} ) = SearchingAlias |
110 | onionNodeInfo (OnionDestination ni _) = ni | 121 | onionAliasSelector (OnionDestination{onionAliasSelector' = sel}) = sel |
111 | 122 | ||
112 | onionKey :: OnionDestination r -> Maybe PublicKey | 123 | onionKey :: OnionDestination r -> PublicKey |
113 | onionKey od = Just $ id2key . nodeId $ onionNodeInfo od | 124 | onionKey od = id2key . nodeId $ onionNodeInfo od |
114 | 125 | ||
115 | instance Sized (OnionMessage Encrypted) where | 126 | instance Sized (OnionMessage Encrypted) where |
116 | size = VarSize $ \case | 127 | size = VarSize $ \case |
@@ -152,7 +163,7 @@ onion bs saddr getf = do (f,(assym,ret3)) <- runGet ((,) <$> getf <*> getOnionRe | |||
152 | oaddr <- onionToOwner assym ret3 saddr | 163 | oaddr <- onionToOwner assym ret3 saddr |
153 | return (f assym, oaddr) | 164 | return (f assym, oaddr) |
154 | 165 | ||
155 | parseOnionAddr :: (SockAddr -> Nonce8 -> IO (Maybe (NodeInfo,r))) | 166 | parseOnionAddr :: (SockAddr -> Nonce8 -> IO (Maybe (OnionDestination r))) |
156 | -> (ByteString, SockAddr) | 167 | -> (ByteString, SockAddr) |
157 | -> IO (Either (OnionMessage Encrypted,OnionDestination r) | 168 | -> IO (Either (OnionMessage Encrypted,OnionDestination r) |
158 | (ByteString,SockAddr)) | 169 | (ByteString,SockAddr)) |
@@ -167,11 +178,11 @@ parseOnionAddr lookupSender (msg,saddr) | |||
167 | Just (Right msg@(OnionAnnounceResponse n8 _ _)) -> do | 178 | Just (Right msg@(OnionAnnounceResponse n8 _ _)) -> do |
168 | maddr <- lookupSender saddr n8 | 179 | maddr <- lookupSender saddr n8 |
169 | maybe (return right) -- Response unsolicited or too late. | 180 | maybe (return right) -- Response unsolicited or too late. |
170 | (return . Left . \(ni,r) -> (msg,OnionDestination ni (Just r))) | 181 | (return . Left . \od -> (msg,od)) |
171 | maddr | 182 | maddr |
172 | Just (Right msg@(OnionToRouteResponse asym)) -> do | 183 | Just (Right msg@(OnionToRouteResponse asym)) -> do |
173 | let ni = asymNodeInfo saddr asym | 184 | let ni = asymNodeInfo saddr asym |
174 | return $ Left (msg, OnionDestination ni Nothing) | 185 | return $ Left (msg, OnionDestination SearchingAlias ni Nothing) |
175 | _ -> return right | 186 | _ -> return right |
176 | 187 | ||
177 | getOnionReply :: Word8 -> Maybe (Get (OnionMessage Encrypted)) | 188 | getOnionReply :: Word8 -> Maybe (Get (OnionMessage Encrypted)) |
@@ -191,10 +202,10 @@ encodeOnionAddr :: (NodeInfo -> r -> IO (Maybe OnionRoute)) | |||
191 | encodeOnionAddr _ (msg,OnionToOwner ni p) = | 202 | encodeOnionAddr _ (msg,OnionToOwner ni p) = |
192 | return $ Just ( runPut $ putResponse (OnionResponse p msg) | 203 | return $ Just ( runPut $ putResponse (OnionResponse p msg) |
193 | , nodeAddr ni ) | 204 | , nodeAddr ni ) |
194 | encodeOnionAddr _ (msg,OnionDestination _ Nothing ) = do | 205 | encodeOnionAddr _ (msg,OnionDestination _ _ Nothing) = do |
195 | hPutStrLn stderr $ "ONION encode missing routeid" | 206 | hPutStrLn stderr $ "ONION encode missing routeid" |
196 | return Nothing | 207 | return Nothing |
197 | encodeOnionAddr getRoute (msg,OnionDestination ni (Just rid)) = do | 208 | encodeOnionAddr getRoute (msg,OnionDestination _ ni (Just rid)) = do |
198 | let go route = do | 209 | let go route = do |
199 | return ( runPut $ putRequest $ wrapForRoute msg ni route | 210 | return ( runPut $ putRequest $ wrapForRoute msg ni route |
200 | , nodeAddr $ routeNodeA route) | 211 | , nodeAddr $ routeNodeA route) |
@@ -599,26 +610,19 @@ instance Sized OnionData where | |||
599 | VarSize f -> f req | 610 | VarSize f -> f req |
600 | 611 | ||
601 | 612 | ||
602 | selectKey :: TransportCrypto -> OnionMessage Identity -> OnionDestination r -> IO (SecretKey, PublicKey) | 613 | selectKey :: TransportCrypto -> OnionMessage f -> OnionDestination r -> IO (SecretKey, PublicKey) |
603 | selectKey crypto | 614 | selectKey crypto _ rpath@(OnionDestination (AnnouncingAlias pkey) _ _) |
604 | (OnionAnnounce a@Assym { assymData = Identity (AnnounceRequest _ pkey akey, _) }) | 615 | = atomically $ do ks <- filter (\(sk,pk) -> pk == id2key pkey) |
605 | rpath | 616 | <$> readTVar (userKeys crypto) |
606 | | (akey /= zeroID) = atomically $ do | 617 | maybe (return $ aliasKey crypto rpath) |
607 | ks <- filter (\(sk,pk) -> pk == id2key pkey) | 618 | return |
608 | <$> readTVar (userKeys crypto) | 619 | (listToMaybe ks) |
609 | maybe (return $ aliasKey crypto rpath) | ||
610 | return | ||
611 | (listToMaybe ks) | ||
612 | selectKey crypto msg rpath = return $ aliasKey crypto rpath | 620 | selectKey crypto msg rpath = return $ aliasKey crypto rpath |
613 | 621 | ||
614 | encrypt :: TransportCrypto -> OnionMessage Identity -> OnionDestination r -> IO (OnionMessage Encrypted, OnionDestination r) | 622 | encrypt :: TransportCrypto -> OnionMessage Identity -> OnionDestination r -> IO (OnionMessage Encrypted, OnionDestination r) |
615 | encrypt crypto msg rpath = do | 623 | encrypt crypto msg rpath = do |
616 | (skey,pkey) <- selectKey crypto msg rpath | 624 | (skey,pkey) <- selectKey crypto msg rpath -- source key |
617 | let skey = fst $ aliasKey crypto rpath | 625 | let okey = onionKey rpath -- destination key |
618 | |||
619 | -- The OnionToMe case shouldn't happen, but we'll use our own public | ||
620 | -- key in this situation. | ||
621 | okey = fromMaybe (transportPublic crypto) $ onionKey rpath | ||
622 | return ( transcode ( (. (runIdentity . either id assymData)) | 626 | return ( transcode ( (. (runIdentity . either id assymData)) |
623 | . encryptMessage skey okey) | 627 | . encryptMessage skey okey) |
624 | msg | 628 | msg |
@@ -632,11 +636,13 @@ encryptMessage skey destKey n a = ToxCrypto.encrypt secret plain | |||
632 | plain = encodePlain a | 636 | plain = encodePlain a |
633 | 637 | ||
634 | decrypt :: TransportCrypto -> OnionMessage Encrypted -> OnionDestination r -> IO (Either String (OnionMessage Identity, OnionDestination r)) | 638 | decrypt :: TransportCrypto -> OnionMessage Encrypted -> OnionDestination r -> IO (Either String (OnionMessage Identity, OnionDestination r)) |
635 | decrypt crypto msg addr = return $ do | 639 | decrypt crypto msg addr = do |
636 | msg <- sequenceMessage $ transcode (\n -> decryptMessage (aliasKey crypto addr) n . left (senderkey addr)) msg | 640 | (skey,pkey) <- selectKey crypto msg addr |
641 | return $ do | ||
642 | msg <- sequenceMessage $ transcode (\n -> decryptMessage (skey,pkey) n . left (senderkey addr)) msg | ||
637 | Right (msg, addr) | 643 | Right (msg, addr) |
638 | 644 | ||
639 | senderkey :: OnionDestination r -> t -> (Maybe PublicKey, t) | 645 | senderkey :: OnionDestination r -> t -> (PublicKey, t) |
640 | senderkey addr e = (onionKey addr, e) | 646 | senderkey addr e = (onionKey addr, e) |
641 | 647 | ||
642 | aliasKey :: TransportCrypto -> OnionDestination r -> (SecretKey,PublicKey) | 648 | aliasKey :: TransportCrypto -> OnionDestination r -> (SecretKey,PublicKey) |
@@ -649,17 +655,14 @@ dhtKey crypto = (transportSecret &&& transportPublic) crypto | |||
649 | decryptMessage :: Serialize x => | 655 | decryptMessage :: Serialize x => |
650 | (SecretKey,PublicKey) | 656 | (SecretKey,PublicKey) |
651 | -> Nonce24 | 657 | -> Nonce24 |
652 | -> Either (Maybe PublicKey, Encrypted x) | 658 | -> Either (PublicKey, Encrypted x) |
653 | (Assym (Encrypted x)) | 659 | (Assym (Encrypted x)) |
654 | -> (Either String ∘ Identity) x | 660 | -> (Either String ∘ Identity) x |
655 | decryptMessage crypto n arg | 661 | decryptMessage crypto n arg = plain $ ToxCrypto.decrypt secret e |
656 | | Just secret <- msecret = plain $ ToxCrypto.decrypt secret e | ||
657 | | otherwise = Composed $ Left "decryptMessage: Unknown sender" | ||
658 | where | 662 | where |
659 | msecret = do sender <- mkey | 663 | secret = computeSharedSecret (fst crypto) sender n |
660 | Just $ computeSharedSecret (fst crypto) sender n | 664 | (sender,e) = either id (senderKey &&& assymData) arg |
661 | (mkey,e) = either id (Just . senderKey &&& assymData) arg | 665 | plain = Composed . fmap Identity . (>>= decodePlain) |
662 | plain = Composed . fmap Identity . (>>= decodePlain) | ||
663 | 666 | ||
664 | 667 | ||
665 | sequenceMessage :: Applicative m => OnionMessage (m ∘ f) -> m (OnionMessage f) | 668 | sequenceMessage :: Applicative m => OnionMessage (m ∘ f) -> m (OnionMessage f) |
@@ -751,4 +754,4 @@ encodeDataToRoute :: TransportCrypto | |||
751 | encodeDataToRoute crypto (dta, Rendezvous pub ni) | 754 | encodeDataToRoute crypto (dta, Rendezvous pub ni) |
752 | = Just ( OnionToRoute pub -- Public key of destination node | 755 | = Just ( OnionToRoute pub -- Public key of destination node |
753 | dta | 756 | dta |
754 | , OnionDestination ni Nothing ) | 757 | , OnionDestination SearchingAlias ni Nothing ) |