summaryrefslogtreecommitdiff
path: root/Presence
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2018-11-05 05:54:00 -0500
committerJoe Crayne <joe@jerkface.net>2018-11-05 16:28:25 -0500
commitdd9dad21a830e932ab873510c41ce1a098bc78b8 (patch)
tree9c8cd38ac353509c1330eecf38101a5ee10dead0 /Presence
parent361209738d454309bf93ed49d9343ea264b21fb8 (diff)
Respond to XMPP discovery queries.
Diffstat (limited to 'Presence')
-rw-r--r--Presence/Stanza/Parse.hs8
-rw-r--r--Presence/Stanza/Types.hs4
-rw-r--r--Presence/XMPPServer.hs76
3 files changed, 78 insertions, 10 deletions
diff --git a/Presence/Stanza/Parse.hs b/Presence/Stanza/Parse.hs
index e2a9efdd..af95530f 100644
--- a/Presence/Stanza/Parse.hs
+++ b/Presence/Stanza/Parse.hs
@@ -46,6 +46,10 @@ grokStanzaIQGet stanza = do
46 case tagName tag of 46 case tagName tag of
47 "{urn:xmpp:ping}ping" -> return Ping 47 "{urn:xmpp:ping}ping" -> return Ping
48 "{jabber:iq:roster}query" -> return RequestRoster 48 "{jabber:iq:roster}query" -> return RequestRoster
49 "{http://jabber.org/protocol/disco#items}query"
50 -> return RequestItems
51 "{http://jabber.org/protocol/disco#info}query"
52 -> return RequestInfo
49 name -> return $ UnrecognizedQuery name 53 name -> return $ UnrecognizedQuery name
50 54
51grokStanzaIQResult :: XML.Event -> NestingXML o IO (Maybe StanzaType) 55grokStanzaIQResult :: XML.Event -> NestingXML o IO (Maybe StanzaType)
@@ -55,6 +59,10 @@ grokStanzaIQResult stanza = do
55 case tagName tag of 59 case tagName tag of
56 "{jabber:iq:version}query" | nameNamespace (tagName stanza)==Just "jabber:client" 60 "{jabber:iq:version}query" | nameNamespace (tagName stanza)==Just "jabber:client"
57 -> parseClientVersion 61 -> parseClientVersion
62 "{http://jabber.org/protocol/disco#items}query"
63 -> return $ Just Items
64 "{http://jabber.org/protocol/disco#info}query"
65 -> return $ Just Info
58 _ -> return Nothing 66 _ -> return Nothing
59 67
60grokStanzaIQSet :: XML.Event -> NestingXML o IO (Maybe StanzaType) 68grokStanzaIQSet :: XML.Event -> NestingXML o IO (Maybe StanzaType)
diff --git a/Presence/Stanza/Types.hs b/Presence/Stanza/Types.hs
index 6b402f4d..cbb156a0 100644
--- a/Presence/Stanza/Types.hs
+++ b/Presence/Stanza/Types.hs
@@ -34,6 +34,10 @@ data StanzaType
34 | Pong 34 | Pong
35 | RequestResource (Maybe Text) (Maybe Text) -- ^ Client's name for this host followed by client's requested resource id. 35 | RequestResource (Maybe Text) (Maybe Text) -- ^ Client's name for this host followed by client's requested resource id.
36 | SetResource 36 | SetResource
37 | RequestItems
38 | Items
39 | RequestInfo
40 | Info
37 | SessionRequest 41 | SessionRequest
38 | UnrecognizedQuery Name 42 | UnrecognizedQuery Name
39 | RequestRoster 43 | RequestRoster
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs
index f9938570..dcbc9bf5 100644
--- a/Presence/XMPPServer.hs
+++ b/Presence/XMPPServer.hs
@@ -1,9 +1,10 @@
1{-# LANGUAGE CPP #-} 1{-# LANGUAGE CPP #-}
2{-# LANGUAGE OverloadedStrings #-} 2{-# LANGUAGE DoAndIfThenElse #-}
3{-# LANGUAGE RankNTypes #-}
4{-# LANGUAGE FlexibleInstances #-} -- instance for TChan Event
5{-# LANGUAGE DoAndIfThenElse #-}
6{-# LANGUAGE ExistentialQuantification #-} 3{-# LANGUAGE ExistentialQuantification #-}
4{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE OverloadedStrings #-}
6{-# LANGUAGE RankNTypes #-}
7{-# LANGUAGE TupleSections #-}
7module XMPPServer 8module XMPPServer
8 ( xmppServer 9 ( xmppServer
9 , forkXmpp 10 , forkXmpp
@@ -92,7 +93,7 @@ import Data.XML.Types as XML
92import Data.Maybe 93import Data.Maybe
93import Data.Monoid ( (<>) ) 94import Data.Monoid ( (<>) )
94import Data.Text (Text) 95import Data.Text (Text)
95import qualified Data.Text as Text (pack,unpack,intercalate,drop) 96import qualified Data.Text as Text (pack,unpack,intercalate,drop,toLower)
96import qualified Data.Map as Map 97import qualified Data.Map as Map
97import Data.Set (Set, (\\) ) 98import Data.Set (Set, (\\) )
98import qualified Data.Set as Set 99import qualified Data.Set as Set
@@ -626,6 +627,40 @@ makePing namespace mid to from =
626 , EventEndElement "{urn:xmpp:ping}ping" 627 , EventEndElement "{urn:xmpp:ping}ping"
627 , EventEndElement $ mkname namespace "iq"] 628 , EventEndElement $ mkname namespace "iq"]
628 629
630makeInfo :: Maybe Text -> Text -> Maybe Text -> [Event]
631makeInfo mid from mto = concat
632 [ [ EventBeginElement "{jabber:client}iq"
633 $ consid mid $ maybe id (\to -> (("to", [ContentText to]) :)) mto
634 [("from", [ContentText from])
635 ,("type", [ContentText "result"])]
636 , EventBeginElement "{http://jabber.org/protocol/disco#info}query" []
637 , EventBeginElement "{http://jabber.org/protocol/disco#info}identity"
638 [("category",[ContentText "server"])
639 ,("type",[ContentText "im"])]
640 , EventEndElement "{http://jabber.org/protocol/disco#info}identity"
641 , EventBeginElement "{http://jabber.org/protocol/disco#info}feature"
642 [("var",[ContentText "http://jabber.org/protocol/disco#info"])]
643 , EventEndElement "{http://jabber.org/protocol/disco#info}feature" ]
644 , [] -- todo
645 , [ EventEndElement "{http://jabber.org/protocol/disco#info}query"
646 , EventEndElement "{jabber:client}iq" ]
647 ]
648
649makeItemList :: Maybe Text -> [(Text,Maybe Text)] -> Text -> Maybe Text -> [Event]
650makeItemList mid items from mto = concat
651 [ [ EventBeginElement "{jabber:client}iq"
652 $ consid mid $ maybe id (\to -> (("to", [ContentText to]) :)) mto
653 [("from", [ContentText from])
654 ,("type", [ContentText "result"])]
655 , EventBeginElement "{http://jabber.org/protocol/disco#items}query" []]
656 , do (jid,name) <- items
657 [ EventBeginElement "{http://jabber.org/protocol/disco#items}item"
658 $ maybe id (\n -> (("name", [ContentText n]) :)) name [ ("jid", [ContentText jid]) ],
659 EventEndElement "{http://jabber.org/protocol/disco#items}item" ]
660 , [ EventEndElement "{http://jabber.org/protocol/disco#items}query"
661 , EventEndElement "{jabber:client}iq" ]
662 ]
663
629iq_bind_reply :: Maybe Text -> Text -> [XML.Event] 664iq_bind_reply :: Maybe Text -> Text -> [XML.Event]
630iq_bind_reply mid jid = 665iq_bind_reply mid jid =
631 [ EventBeginElement "{jabber:client}iq" (consid mid [("type",[ContentText "result"])]) 666 [ EventBeginElement "{jabber:client}iq" (consid mid [("type",[ContentText "result"])])
@@ -908,7 +943,7 @@ forkConnection sv xmpp saddr cdta pingflag src snk stanzas pp_mvar = do
908 -- kwlog $ "queuing: "++show (isempty, stanzaId stanza) 943 -- kwlog $ "queuing: "++show (isempty, stanzaId stanza)
909 notping $ do 944 notping $ do
910 dup <- cloneStanza stanza 945 dup <- cloneStanza stanza
911 let typ = Strict8.pack $ c ++ "<-"++(concat . take 1 . words $ show (stanzaType dup))++" " 946 let typ = Strict8.pack $ c ++ "<-" ++ stanzaTypeString dup ++ " "
912 c = case auxAddr of 947 c = case auxAddr of
913 Right _ -> "C" 948 Right _ -> "C"
914 Left _ -> "P" 949 Left _ -> "P"
@@ -1209,8 +1244,9 @@ monitor sv params xmpp = do
1209 -} 1244 -}
1210 dup <- cloneStanza stanza 1245 dup <- cloneStanza stanza
1211 1246
1212 forkIO $ do applyStanza sv quitVar xmpp stanza 1247 t <- forkIO $ do applyStanza sv quitVar xmpp stanza
1213 forwardStanza quitVar xmpp stanza 1248 forwardStanza quitVar xmpp stanza
1249 labelThread t $ "process." ++ stanzaTypeString stanza
1214 1250
1215 -- We need to clone in the case the stanza is passed on as for Message. 1251 -- We need to clone in the case the stanza is passed on as for Message.
1216 wantStanzas <- getVerbose XJabber 1252 wantStanzas <- getVerbose XJabber
@@ -1221,7 +1257,7 @@ monitor sv params xmpp = do
1221 | (verbosity>=2) = f 1257 | (verbosity>=2) = f
1222 | otherwise = return () 1258 | otherwise = return ()
1223 notping $ do 1259 notping $ do
1224 let typ = Strict8.pack $ c ++ "->"++(concat . take 1 . words $ show (stanzaType stanza))++" " 1260 let typ = Strict8.pack $ c ++ "->" ++ stanzaTypeString stanza ++ " "
1225 c = case stanzaOrigin stanza of 1261 c = case stanzaOrigin stanza of
1226 LocalPeer -> "*" 1262 LocalPeer -> "*"
1227 ClientOrigin {} -> "C" 1263 ClientOrigin {} -> "C"
@@ -1238,6 +1274,9 @@ monitor sv params xmpp = do
1238 where 1274 where
1239 _ = str :: String 1275 _ = str :: String
1240 1276
1277stanzaTypeString :: StanzaWrap a -> String
1278stanzaTypeString stanza = concat . take 1 . words $ show (stanzaType stanza)
1279
1241applyStanza :: Server PeerAddress ConnectionData releaseKey Event 1280applyStanza :: Server PeerAddress ConnectionData releaseKey Event
1242 -> TMVar () 1281 -> TMVar ()
1243 -> XMPPServerParameters 1282 -> XMPPServerParameters
@@ -1298,6 +1337,23 @@ applyStanza sv quitVar xmpp stanza = case stanzaOrigin stanza of
1298 xmppClientInformSubscription xmpp fail k stanza 1337 xmppClientInformSubscription xmpp fail k stanza
1299 NotifyClientVersion name version -> do 1338 NotifyClientVersion name version -> do
1300 enableClientHacks name version replyto 1339 enableClientHacks name version replyto
1340 RequestInfo -> do
1341 -- TODO ItemNotFound
1342 me <- xmppTellMyNameToClient xmpp k
1343 if fmap Text.toLower (stanzaTo stanza) == Just (Text.toLower me)
1344 then
1345 let reply = makeInfo (stanzaId stanza) me (stanzaFrom stanza)
1346 in sendReply quitVar Info reply replyto
1347 else
1348 let query = "{http://jabber.org/protocol/disco#info}info"
1349 reply = iq_service_unavailable (stanzaId stanza) me query
1350 in sendReply quitVar (Error ServiceUnavailable (head reply)) reply replyto
1351 RequestItems -> do
1352 -- let query = "{http://jabber.org/protocol/disco#items}query"
1353 me <- xmppTellMyNameToClient xmpp k
1354 let items = []
1355 reply = makeItemList (stanzaId stanza) items me (stanzaFrom stanza)
1356 sendReply quitVar Items reply replyto
1301 UnrecognizedQuery query -> do 1357 UnrecognizedQuery query -> do
1302 me <- xmppTellMyNameToClient xmpp k 1358 me <- xmppTellMyNameToClient xmpp k
1303 let reply = iq_service_unavailable (stanzaId stanza) me query 1359 let reply = iq_service_unavailable (stanzaId stanza) me query