diff options
-rw-r--r-- | Presence/Presence.hs | 26 | ||||
-rw-r--r-- | examples/dhtd.hs | 63 |
2 files changed, 56 insertions, 33 deletions
diff --git a/Presence/Presence.hs b/Presence/Presence.hs index 77689d1e..ed1c5033 100644 --- a/Presence/Presence.hs +++ b/Presence/Presence.hs | |||
@@ -39,7 +39,8 @@ import Data.XML.Types (Event) | |||
39 | import System.Posix.Types (UserID,CPid) | 39 | import System.Posix.Types (UserID,CPid) |
40 | import Control.Applicative | 40 | import Control.Applicative |
41 | import Crypto.Error.Types (CryptoFailable (..)) | 41 | import Crypto.Error.Types (CryptoFailable (..)) |
42 | import Crypto.PubKey.Curve25519 (publicKey, secretKey, toPublic) | 42 | import Crypto.PubKey.Curve25519 (SecretKey,toPublic) |
43 | import Text.Read (readMaybe) | ||
43 | 44 | ||
44 | import LockedChan (LockedChan) | 45 | import LockedChan (LockedChan) |
45 | import TraversableT | 46 | import TraversableT |
@@ -51,6 +52,8 @@ import ConsoleWriter | |||
51 | import ClientState | 52 | import ClientState |
52 | import Util | 53 | import Util |
53 | import qualified Connection | 54 | import qualified Connection |
55 | import Network.Tox.NodeId (id2key) | ||
56 | import Crypto.Tox (decodeSecret) | ||
54 | 57 | ||
55 | isPeerKey :: ConnectionKey -> Bool | 58 | isPeerKey :: ConnectionKey -> Bool |
56 | isPeerKey k = case k of { PeerKey {} -> True ; _ -> False } | 59 | isPeerKey k = case k of { PeerKey {} -> True ; _ -> False } |
@@ -65,9 +68,22 @@ localJID user "." resource = do | |||
65 | localJID user profile resource = | 68 | localJID user profile resource = |
66 | return $ user <> "@" <> profile <> "/" <> resource | 69 | return $ user <> "@" <> profile <> "/" <> resource |
67 | 70 | ||
71 | -- | These hooks will be invoked in order to connect to *.tox hosts in the | ||
72 | -- user's roster. | ||
73 | -- | ||
74 | -- The parameter k is a lookup key corresponding to an XMPP client. Each | ||
75 | -- unique value should be able to hold a reference to the ToxID identity which | ||
76 | -- should stay online until all interested keys have run 'deactivateAccount'. | ||
68 | data ToxManager k = ToxManager | 77 | data ToxManager k = ToxManager |
69 | { activateAccount :: k -> Text -> IO () | 78 | -- | Put the given ToxID online. |
79 | { activateAccount :: k -> Text -> SecretKey -> IO () | ||
80 | -- | Take the given ToxID offline (assuming no other /k/ has a claim). | ||
70 | , deactivateAccount :: k -> Text -> IO () | 81 | , deactivateAccount :: k -> Text -> IO () |
82 | -- | Try to connect to the remote peer (or not). | ||
83 | -- | ||
84 | -- The arguments are our public key (in hostname format) followed by | ||
85 | -- their public key (in hostname format) and the Policy to set for this | ||
86 | -- link. | ||
71 | , setToxConnectionPolicy :: Text -> Text -> Connection.Policy -> IO () | 87 | , setToxConnectionPolicy :: Text -> Text -> Connection.Policy -> IO () |
72 | } | 88 | } |
73 | 89 | ||
@@ -196,9 +212,9 @@ chooseResourceName state k addr clientsNameForMe desired = do | |||
196 | -- TODO: Tox key profile. | 212 | -- TODO: Tox key profile. |
197 | secs <- configText ConfigFiles.getSecrets user wanted_profile | 213 | secs <- configText ConfigFiles.getSecrets user wanted_profile |
198 | case secs of | 214 | case secs of |
199 | sec:_ | CryptoPassed s <- secretKey (Text.encodeUtf8 sec) | 215 | sec:_ | Just s <- decodeSecret (Text.encodeUtf8 sec) |
200 | , CryptoPassed (toPublic s) == publicKey (Text.encodeUtf8 pub) | 216 | , Just (toPublic s) == fmap id2key (readMaybe $ Text.unpack pub) |
201 | -> do activateAccount toxman k wanted_profile | 217 | -> do activateAccount toxman k wanted_profile s |
202 | return wanted_profile | 218 | return wanted_profile |
203 | _ -> do | 219 | _ -> do |
204 | -- XXX: We should probably fail to connect when an | 220 | -- XXX: We should probably fail to connect when an |
diff --git a/examples/dhtd.hs b/examples/dhtd.hs index 73ae5a57..fbfca86f 100644 --- a/examples/dhtd.hs +++ b/examples/dhtd.hs | |||
@@ -994,6 +994,18 @@ newXmmpSource = _todo | |||
994 | newXmmpSink :: Tox.NetCryptoSession -> IO (C.Sink (Flush Tox.CryptoMessage) IO ()) | 994 | newXmmpSink :: Tox.NetCryptoSession -> IO (C.Sink (Flush Tox.CryptoMessage) IO ()) |
995 | newXmmpSink = _todo | 995 | newXmmpSink = _todo |
996 | 996 | ||
997 | -- | TODO | ||
998 | -- | ||
999 | -- These hooks will be invoked in order to connect to *.tox hosts in a user's | ||
1000 | -- XMPP roster. | ||
1001 | toxman :: Tox.Tox -> ToxManager k | ||
1002 | toxman tox = ToxManager | ||
1003 | { activateAccount = \k pubname seckey -> return () | ||
1004 | , deactivateAccount = \k pubname -> return () | ||
1005 | , setToxConnectionPolicy = \me them policy -> return () | ||
1006 | } | ||
1007 | |||
1008 | |||
997 | announceToxXMPPClients :: TChan ((ConnectionKey,SockAddr), Tcp.ConnectionEvent XML.Event) | 1009 | announceToxXMPPClients :: TChan ((ConnectionKey,SockAddr), Tcp.ConnectionEvent XML.Event) |
998 | -> SockAddr | 1010 | -> SockAddr |
999 | -> SockAddr | 1011 | -> SockAddr |
@@ -1012,6 +1024,7 @@ announceToxXMPPClients echan laddr saddr pingflag tsrc tsnk | |||
1012 | xsnk = flushPassThrough xmppToTox =$= tsnk | 1024 | xsnk = flushPassThrough xmppToTox =$= tsnk |
1013 | 1025 | ||
1014 | 1026 | ||
1027 | |||
1015 | main :: IO () | 1028 | main :: IO () |
1016 | main = runResourceT $ liftBaseWith $ \resT -> do | 1029 | main = runResourceT $ liftBaseWith $ \resT -> do |
1017 | args <- getArgs | 1030 | args <- getArgs |
@@ -1027,28 +1040,6 @@ main = runResourceT $ liftBaseWith $ \resT -> do | |||
1027 | 1040 | ||
1028 | announcer <- forkAnnouncer | 1041 | announcer <- forkAnnouncer |
1029 | 1042 | ||
1030 | let toxman = ToxManager | ||
1031 | { activateAccount = \k pubkey -> return () | ||
1032 | , deactivateAccount = \k pubkey -> return () | ||
1033 | , setToxConnectionPolicy = \me them policy -> return () | ||
1034 | } | ||
1035 | |||
1036 | -- XMPP initialization | ||
1037 | cw <- newConsoleWriter | ||
1038 | serverVar <- atomically $ newEmptyTMVar | ||
1039 | state <- newPresenceState cw (Just toxman) serverVar | ||
1040 | |||
1041 | -- XMPP stanza handling | ||
1042 | sv <- resT $ xmppServer (presenceHooks state (verbosity opts)) | ||
1043 | -- We now have a server object but it's not ready to use until | ||
1044 | -- we put it into the 'server' field of our /state/ record. | ||
1045 | |||
1046 | conns <- xmppConnections sv | ||
1047 | |||
1048 | atomically $ do | ||
1049 | putTMVar serverVar (sv,conns) -- Okay, now it's ready. :) | ||
1050 | -- FIXME: This is error prone. | ||
1051 | |||
1052 | 1043 | ||
1053 | (quitBt,btdhts,btips,baddrs) <- case portbt opts of | 1044 | (quitBt,btdhts,btips,baddrs) <- case portbt opts of |
1054 | "" -> return (return (), Map.empty,return [],[]) | 1045 | "" -> return (return (), Map.empty,return [],[]) |
@@ -1145,12 +1136,6 @@ main = runResourceT $ liftBaseWith $ \resT -> do | |||
1145 | "" -> return (Nothing,return (), Map.empty, return [],[]) | 1136 | "" -> return (Nothing,return (), Map.empty, return [],[]) |
1146 | toxport -> do | 1137 | toxport -> do |
1147 | addrTox <- getBindAddress toxport (ip6tox opts) | 1138 | addrTox <- getBindAddress toxport (ip6tox opts) |
1148 | atomically $ Tox.addNewSessionHook netCryptoSessionsState $ \mbNoSpam netcrypto -> do | ||
1149 | let Just pingMachine = Tox.ncPingMachine netcrypto | ||
1150 | pingflag = readTVar (pingFlag pingMachine) | ||
1151 | xmppSrc <- newXmmpSource netcrypto | ||
1152 | xmppSink <- newXmmpSink netcrypto | ||
1153 | announceToxXMPPClients (xmppEventChannel sv) addrTox (Tox.ncSockAddr netcrypto) pingflag xmppSrc xmppSink | ||
1154 | hPutStrLn stderr $ "Supplied key: " ++ show (fmap (Tox.key2id . toPublic) (dhtkey opts)) | 1139 | hPutStrLn stderr $ "Supplied key: " ++ show (fmap (Tox.key2id . toPublic) (dhtkey opts)) |
1155 | tox <- Tox.newTox keysdb | 1140 | tox <- Tox.newTox keysdb |
1156 | addrTox | 1141 | addrTox |
@@ -1321,8 +1306,30 @@ main = runResourceT $ liftBaseWith $ \resT -> do | |||
1321 | ips = readExternals Tox.nodeAddr [ Tox.routing4 $ Tox.toxRouting tox | 1306 | ips = readExternals Tox.nodeAddr [ Tox.routing4 $ Tox.toxRouting tox |
1322 | , Tox.routing6 $ Tox.toxRouting tox ] | 1307 | , Tox.routing6 $ Tox.toxRouting tox ] |
1323 | return (Just tox, quitTox, dhts, ips, [addrTox]) | 1308 | return (Just tox, quitTox, dhts, ips, [addrTox]) |
1309 | |||
1324 | _ <- UPNP.requestPorts "dht-client" $ map (Datagram,) $ baddrs ++ taddrs | 1310 | _ <- UPNP.requestPorts "dht-client" $ map (Datagram,) $ baddrs ++ taddrs |
1325 | 1311 | ||
1312 | -- XMPP initialization | ||
1313 | cw <- newConsoleWriter | ||
1314 | serverVar <- atomically $ newEmptyTMVar | ||
1315 | state <- newPresenceState cw (toxman <$> mbtox) serverVar | ||
1316 | |||
1317 | sv <- resT $ xmppServer (presenceHooks state (verbosity opts)) | ||
1318 | -- We now have a server object but it's not ready to use until | ||
1319 | -- we put it into the 'server' field of our /state/ record. | ||
1320 | conns <- xmppConnections sv | ||
1321 | atomically $ do | ||
1322 | putTMVar serverVar (sv,conns) -- Okay, now it's ready. :) | ||
1323 | -- FIXME: This is error prone. | ||
1324 | |||
1325 | forM_ (take 1 taddrs) $ \addrTox -> do | ||
1326 | atomically $ Tox.addNewSessionHook netCryptoSessionsState $ \mbNoSpam netcrypto -> do | ||
1327 | let Just pingMachine = Tox.ncPingMachine netcrypto | ||
1328 | pingflag = readTVar (pingFlag pingMachine) | ||
1329 | xmppSrc <- newXmmpSource netcrypto | ||
1330 | xmppSink <- newXmmpSink netcrypto | ||
1331 | announceToxXMPPClients (xmppEventChannel sv) addrTox (Tox.ncSockAddr netcrypto) pingflag xmppSrc xmppSink | ||
1332 | |||
1326 | let dhts = Map.union btdhts toxdhts | 1333 | let dhts = Map.union btdhts toxdhts |
1327 | 1334 | ||
1328 | (waitForSignal, checkQuit) <- do | 1335 | (waitForSignal, checkQuit) <- do |