summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--OnionRouter.hs24
-rw-r--r--src/Crypto/Tox.hs4
-rw-r--r--src/Network/QueryResponse.hs3
-rw-r--r--src/Network/Tox.hs18
-rw-r--r--src/Network/Tox/Onion/Transport.hs17
5 files changed, 46 insertions, 20 deletions
diff --git a/OnionRouter.hs b/OnionRouter.hs
index 7a48aaab..40112e6a 100644
--- a/OnionRouter.hs
+++ b/OnionRouter.hs
@@ -33,21 +33,21 @@ newtype RouteId = RouteId Int
33 deriving Show 33 deriving Show
34 34
35data OnionRouter = OnionRouter 35data OnionRouter = OnionRouter
36 { pendingQueries :: TVar (Word64Map NodeId) 36 { pendingQueries :: TVar (Word64Map NodeId) -- TODO: routeNonce belongs here instead of in routeMap, or just remove routeNonce and use transaction nonce.
37 , routeMap :: TVar (IntMap RouteRecord) 37 , routeMap :: TVar (IntMap RouteRecord)
38 , trampolineNodes :: TVar (IntMap NodeInfo) 38 , trampolineNodes :: TVar (IntMap NodeInfo)
39 , trampolineIds :: TVar (HashMap NodeId Int) 39 , trampolineIds :: TVar (HashMap NodeId Int)
40 , trampolineCount :: TVar Int 40 , trampolineCount :: TVar Int
41 , onionDRG :: TVar ChaChaDRG 41 , onionDRG :: TVar ChaChaDRG
42 , routeThread :: ThreadId 42 , routeThread :: ThreadId
43 , pendingRoutes :: IntMap (TVar Bool) 43 , pendingRoutes :: IntMap (TVar Bool)
44 , routeLog :: TChan String 44 , routeLog :: TChan String
45 } 45 }
46 46
47data RouteRecord = RouteRecord 47data RouteRecord = RouteRecord
48 { storedRoute :: OnionRoute 48 { storedRoute :: OnionRoute
49 , responseCount :: Int 49 , responseCount :: !Int
50 , timeoutCount :: Int 50 , timeoutCount :: !Int
51 } 51 }
52 52
53-- Onion paths have different timeouts depending on whether the path is 53-- Onion paths have different timeouts depending on whether the path is
@@ -230,7 +230,8 @@ handleEvent getnodes or e@(BuildRoute (RouteId rid)) = do
230 [ "ONION trampolines: " ++ show ts 230 [ "ONION trampolines: " ++ show ts
231 , "ONION query results: " ++ show nodes ] 231 , "ONION query results: " ++ show nodes ]
232 case nodes of 232 case nodes of
233 [a,b,c] -> do -- | distinct3by nodeClass a b c -> do 233 [a,b,c] | distinct3by nodeClass a b c -> do
234 atomically $ writeTChan (routeLog or) $ unwords [ "ONION using route:", show $ nodeAddr a, show $ nodeAddr b, show $ nodeAddr c]
234 return $ Just OnionRoute 235 return $ Just OnionRoute
235 { routeNonce = n24 236 { routeNonce = n24
236 , routeAliasA = asec 237 , routeAliasA = asec
@@ -240,6 +241,9 @@ handleEvent getnodes or e@(BuildRoute (RouteId rid)) = do
240 , routeNodeB = b 241 , routeNodeB = b
241 , routeNodeC = c 242 , routeNodeC = c
242 } 243 }
244 [a,b,c] -> do
245 atomically $ writeTChan (routeLog or) $ unwords [ "ONION Discarding insecure route:", show $ nodeAddr a, show $ nodeAddr b, show $ nodeAddr c]
246 return Nothing
243 _ -> return Nothing 247 _ -> return Nothing
244 writeTVar (onionDRG or) drg' 248 writeTVar (onionDRG or) drg'
245 return $ getr 249 return $ getr
diff --git a/src/Crypto/Tox.hs b/src/Crypto/Tox.hs
index 0df06054..6660fc13 100644
--- a/src/Crypto/Tox.hs
+++ b/src/Crypto/Tox.hs
@@ -93,7 +93,7 @@ instance Data Auth where
93 -- Well, this is a little wonky... XXX 93 -- Well, this is a little wonky... XXX
94 gunfold k z c = k (z (Auth . Poly1305.Auth . (BA.convert :: ByteString -> Bytes))) 94 gunfold k z c = k (z (Auth . Poly1305.Auth . (BA.convert :: ByteString -> Bytes)))
95 toConstr _ = con_Auth 95 toConstr _ = con_Auth
96 dataTypeOf _ = mkDataType "ToxCrypto" [con_Auth] 96 dataTypeOf _ = mkDataType "Crypto.Tox" [con_Auth]
97con_Auth :: Constr 97con_Auth :: Constr
98con_Auth = mkConstr (dataTypeOf (Auth (error "con_Auth"))) "Auth" [] Prefix 98con_Auth = mkConstr (dataTypeOf (Auth (error "con_Auth"))) "Auth" [] Prefix
99instance Serialize Auth where 99instance Serialize Auth where
@@ -340,6 +340,8 @@ newtype SymmetricKey = SymmetricKey ByteString
340data TransportCrypto = TransportCrypto 340data TransportCrypto = TransportCrypto
341 { transportSecret :: SecretKey 341 { transportSecret :: SecretKey
342 , transportPublic :: PublicKey 342 , transportPublic :: PublicKey
343 , onionAliasSecret :: SecretKey
344 , onionAliasPublic :: PublicKey
343 , transportSymmetric :: STM SymmetricKey 345 , transportSymmetric :: STM SymmetricKey
344 , transportNewNonce :: STM Nonce24 346 , transportNewNonce :: STM Nonce24
345 } 347 }
diff --git a/src/Network/QueryResponse.hs b/src/Network/QueryResponse.hs
index 70d981e2..27c89674 100644
--- a/src/Network/QueryResponse.hs
+++ b/src/Network/QueryResponse.hs
@@ -187,6 +187,9 @@ data Client err meth tid addr x = forall tbl. Client
187 -- | An action yielding this client\'s own address. It is invoked once 187 -- | An action yielding this client\'s own address. It is invoked once
188 -- on each outbound and inbound packet. It is valid for this to always 188 -- on each outbound and inbound packet. It is valid for this to always
189 -- return the same value. 189 -- return the same value.
190 --
191 -- The argument, if supplied, is the remote address for the transaction.
192 -- This can be used to maintain consistent aliases for specific peers.
190 , clientAddress :: Maybe addr -> IO addr 193 , clientAddress :: Maybe addr -> IO addr
191 -- | Transform a query /tid/ value to an appropriate response /tid/ 194 -- | Transform a query /tid/ value to an appropriate response /tid/
192 -- value. Normally, this would be the identity transformation, but if 195 -- value. Normally, this would be the identity transformation, but if
diff --git a/src/Network/Tox.hs b/src/Network/Tox.hs
index 3860d309..51ee0a4d 100644
--- a/src/Network/Tox.hs
+++ b/src/Network/Tox.hs
@@ -100,7 +100,9 @@ import Data.Word64Map (fitsInInt)
100newCrypto :: IO TransportCrypto 100newCrypto :: IO TransportCrypto
101newCrypto = do 101newCrypto = do
102 secret <- generateSecretKey 102 secret <- generateSecretKey
103 alias <- generateSecretKey
103 let pubkey = toPublic secret 104 let pubkey = toPublic secret
105 aliaspub = toPublic alias
104 (symkey, drg) <- do 106 (symkey, drg) <- do
105 drg0 <- getSystemDRG 107 drg0 <- getSystemDRG
106 return $ randomBytesGenerate 32 drg0 :: IO (ByteString, SystemDRG) 108 return $ randomBytesGenerate 32 drg0 :: IO (ByteString, SystemDRG)
@@ -111,6 +113,8 @@ newCrypto = do
111 return TransportCrypto 113 return TransportCrypto
112 { transportSecret = secret 114 { transportSecret = secret
113 , transportPublic = pubkey 115 , transportPublic = pubkey
116 , onionAliasSecret = alias
117 , onionAliasPublic = aliaspub
114 , transportSymmetric = return $ SymmetricKey symkey 118 , transportSymmetric = return $ SymmetricKey symkey
115 , transportNewNonce = do 119 , transportNewNonce = do
116 drg1 <- readTVar noncevar 120 drg1 <- readTVar noncevar
@@ -205,6 +209,7 @@ data Tox = Tox
205 , toxOnionRoutes :: OnionRouter 209 , toxOnionRoutes :: OnionRouter
206 } 210 }
207 211
212isLocalHost :: SockAddr -> Bool
208isLocalHost (SockAddrInet _ host32) = (fromBE32 host32 == 0x7f000001) 213isLocalHost (SockAddrInet _ host32) = (fromBE32 host32 == 0x7f000001)
209isLocalHost _ = False 214isLocalHost _ = False
210 215
@@ -227,6 +232,14 @@ newKeysDatabase :: IO (TVar Onion.AnnouncedKeys)
227newKeysDatabase = 232newKeysDatabase =
228 atomically $ newTVar $ Onion.AnnouncedKeys PSQ.empty MinMaxPSQ.empty 233 atomically $ newTVar $ Onion.AnnouncedKeys PSQ.empty MinMaxPSQ.empty
229 234
235
236getOnionAlias :: TransportCrypto -> STM NodeInfo -> Maybe (Onion.OnionDestination r) -> IO (Onion.OnionDestination r)
237getOnionAlias crypto dhtself remoteNode = atomically $ do
238 ni <- dhtself
239 let alias = ni { nodeId = key2id (onionAliasPublic crypto) }
240 return $ Onion.OnionDestination alias Nothing
241
242
230newTox :: TVar Onion.AnnouncedKeys -> SockAddr -> IO Tox 243newTox :: TVar Onion.AnnouncedKeys -> SockAddr -> IO Tox
231newTox keydb addr = do 244newTox keydb addr = do
232 udp <- addVerbosity <$> udpTransport addr 245 udp <- addVerbosity <$> udpTransport addr
@@ -249,10 +262,7 @@ newTox keydb addr = do
249 oniondrg <- drgNew 262 oniondrg <- drgNew
250 let onionnet = layerTransport (Onion.decrypt crypto) (Onion.encrypt crypto) onioncrypt 263 let onionnet = layerTransport (Onion.decrypt crypto) (Onion.encrypt crypto) onioncrypt
251 onionclient <- newClient oniondrg onionnet Onion.classify 264 onionclient <- newClient oniondrg onionnet Onion.classify
252 (const $ atomically 265 (getOnionAlias crypto $ R.thisNode <$> readTVar (DHT.routing4 routing))
253 $ flip Onion.OnionDestination Nothing
254 . R.thisNode
255 <$> readTVar (DHT.routing4 routing))
256 (Onion.handlers onionnet routing toks keydb) 266 (Onion.handlers onionnet routing toks keydb)
257 (hookQueries orouter DHT.transactionKey) 267 (hookQueries orouter DHT.transactionKey)
258 (const id) 268 (const id)
diff --git a/src/Network/Tox/Onion/Transport.hs b/src/Network/Tox/Onion/Transport.hs
index b5ac748a..eabd9473 100644
--- a/src/Network/Tox/Onion/Transport.hs
+++ b/src/Network/Tox/Onion/Transport.hs
@@ -457,7 +457,7 @@ peelOnion :: Serialize (Addressed (Forwarding n t))
457 -> Forwarding (S n) t 457 -> Forwarding (S n) t
458 -> Either String (Addressed (Forwarding n t)) 458 -> Either String (Addressed (Forwarding n t))
459peelOnion crypto nonce (Forwarding k fwd) = 459peelOnion crypto nonce (Forwarding k fwd) =
460 fmap runIdentity $ uncomposed $ decryptMessage crypto nonce (Right $ Assym k nonce fwd) 460 fmap runIdentity $ uncomposed $ decryptMessage (dhtKey crypto) nonce (Right $ Assym k nonce fwd)
461 461
462handleOnionResponse :: (KnownPeanoNat n, Sized (ReturnPath n), Serialize (ReturnPath n)) => proxy (S n) -> TransportCrypto -> SockAddr -> UDPTransport -> IO a -> OnionResponse (S n) -> IO a 462handleOnionResponse :: (KnownPeanoNat n, Sized (ReturnPath n), Serialize (ReturnPath n)) => proxy (S n) -> TransportCrypto -> SockAddr -> UDPTransport -> IO a -> OnionResponse (S n) -> IO a
463handleOnionResponse proxy crypto saddr udp kont (OnionResponse path msg) = do 463handleOnionResponse proxy crypto saddr udp kont (OnionResponse path msg) = do
@@ -576,7 +576,7 @@ encrypt crypto msg rpath = ( transcode ( (. (runIdentity . either id assymData))
576 msg 576 msg
577 , rpath) 577 , rpath)
578 where 578 where
579 skey = transportSecret crypto 579 skey = fst $ aliasKey crypto rpath
580 580
581 -- The OnionToMe case shouldn't happen, but we'll use our own public 581 -- The OnionToMe case shouldn't happen, but we'll use our own public
582 -- key in this situation. 582 -- key in this situation.
@@ -592,14 +592,21 @@ encryptMessage skey destKey n a = ToxCrypto.encrypt secret plain
592 592
593decrypt :: TransportCrypto -> OnionMessage Encrypted -> OnionDestination r -> Either String (OnionMessage Identity, OnionDestination r) 593decrypt :: TransportCrypto -> OnionMessage Encrypted -> OnionDestination r -> Either String (OnionMessage Identity, OnionDestination r)
594decrypt crypto msg addr = do 594decrypt crypto msg addr = do
595 msg <- sequenceMessage $ transcode (\n -> decryptMessage crypto n . left (senderkey addr)) msg 595 msg <- sequenceMessage $ transcode (\n -> decryptMessage (aliasKey crypto addr) n . left (senderkey addr)) msg
596 Right (msg, addr) 596 Right (msg, addr)
597 597
598senderkey :: OnionDestination r -> t -> (Maybe PublicKey, t) 598senderkey :: OnionDestination r -> t -> (Maybe PublicKey, t)
599senderkey addr e = (onionKey addr, e) 599senderkey addr e = (onionKey addr, e)
600 600
601aliasKey :: TransportCrypto -> OnionDestination r -> (SecretKey,PublicKey)
602aliasKey crypto (OnionToOwner {}) = (transportSecret &&& transportPublic) crypto
603aliasKey crypto (OnionDestination {}) = (onionAliasSecret &&& onionAliasPublic) crypto
604
605dhtKey :: TransportCrypto -> (SecretKey,PublicKey)
606dhtKey crypto = (transportSecret &&& transportPublic) crypto
607
601decryptMessage :: Serialize x => 608decryptMessage :: Serialize x =>
602 TransportCrypto 609 (SecretKey,PublicKey)
603 -> Nonce24 610 -> Nonce24
604 -> Either (Maybe PublicKey, Encrypted x) 611 -> Either (Maybe PublicKey, Encrypted x)
605 (Assym (Encrypted x)) 612 (Assym (Encrypted x))
@@ -609,7 +616,7 @@ decryptMessage crypto n arg
609 | otherwise = Composed $ Left "decryptMessage: Unknown sender" 616 | otherwise = Composed $ Left "decryptMessage: Unknown sender"
610 where 617 where
611 msecret = do sender <- mkey 618 msecret = do sender <- mkey
612 Just $ computeSharedSecret (transportSecret crypto) sender n 619 Just $ computeSharedSecret (fst crypto) sender n
613 (mkey,e) = either id (Just . senderKey &&& assymData) arg 620 (mkey,e) = either id (Just . senderKey &&& assymData) arg
614 plain = Composed . fmap Identity . (>>= decodePlain) 621 plain = Composed . fmap Identity . (>>= decodePlain)
615 622