summaryrefslogtreecommitdiff
path: root/Presence
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2014-02-15 23:50:41 -0500
committerjoe <joe@jerkface.net>2014-02-15 23:50:41 -0500
commitb0992c304dd48190f7cca0e7222501fd7eb56062 (patch)
treee1830d987f1b22e795eb245a16290d39ed419de8 /Presence
parent9d01ddf6dabc1fdd1a40d7f79b7d21d3e2c6baf1 (diff)
send service-unavailable responses for iq queries
Diffstat (limited to 'Presence')
-rw-r--r--Presence/XMPPServer.hs105
1 files changed, 71 insertions, 34 deletions
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs
index ceb83476..ccdffabe 100644
--- a/Presence/XMPPServer.hs
+++ b/Presence/XMPPServer.hs
@@ -103,6 +103,7 @@ data Stanza
103-} 103-}
104 104
105data StanzaType = Unrecognized | Ping | Pong | RequestResource (Maybe Text) | SetResource 105data StanzaType = Unrecognized | Ping | Pong | RequestResource (Maybe Text) | SetResource
106 | SessionRequest | UnrecognizedQuery Name | Error
106 deriving Show 107 deriving Show
107 108
108data StanzaOrigin = LocalPeer | NetworkOrigin ConnectionKey (TChan Stanza) 109data StanzaOrigin = LocalPeer | NetworkOrigin ConnectionKey (TChan Stanza)
@@ -173,7 +174,7 @@ grokStanzaIQGet stanza = do
173 flip (maybe $ return Nothing) mtag $ \tag -> do 174 flip (maybe $ return Nothing) mtag $ \tag -> do
174 case tagName tag of 175 case tagName tag of
175 "{urn:xmpp:ping}ping" -> return $ Just Ping 176 "{urn:xmpp:ping}ping" -> return $ Just Ping
176 _ -> return Nothing 177 name -> return . Just $ UnrecognizedQuery name
177 178
178grokStanzaIQResult :: Monad m => XML.Event -> NestingXML o m (Maybe StanzaType) 179grokStanzaIQResult :: Monad m => XML.Event -> NestingXML o m (Maybe StanzaType)
179grokStanzaIQResult stanza = do 180grokStanzaIQResult stanza = do
@@ -195,6 +196,8 @@ grokStanzaIQSet stanza = do
195 return . Just $ RequestResource (Just rsc) 196 return . Just $ RequestResource (Just rsc)
196 Just _ -> return Nothing 197 Just _ -> return Nothing
197 Nothing -> return . Just $ RequestResource Nothing 198 Nothing -> return . Just $ RequestResource Nothing
199 "{urn:ietf:params:xml:ns:xmpp-session}session" -> do
200 return $ Just SessionRequest
198 _ -> return Nothing 201 _ -> return Nothing
199 202
200 203
@@ -359,32 +362,6 @@ greet' namespace host =
359consid Nothing = id 362consid Nothing = id
360consid (Just sid) = (("id",[ContentText sid]):) 363consid (Just sid) = (("id",[ContentText sid]):)
361 364
362iq_bind_reply :: Maybe Text -> Text -> [XML.Event]
363iq_bind_reply mid jid =
364 [ EventBeginElement "{jabber:client}iq" (consid mid [("type",[ContentText "result"])])
365 , EventBeginElement "{urn:ietf:params:xml:ns:xmpp-bind}bind"
366 [("xmlns",[ContentText "urn:ietf:params:xml:ns:xmpp-bind"])]
367 , EventBeginElement "{urn:ietf:params:xml:ns:xmpp-bind}jid" []
368 , EventContent (ContentText jid)
369 , EventEndElement "{urn:ietf:params:xml:ns:xmpp-bind}jid"
370 , EventEndElement "{urn:ietf:params:xml:ns:xmpp-bind}bind"
371 , EventEndElement "{jabber:client}iq"
372 ]
373
374{-
375greet namespace =
376 [ EventBeginDocument
377 , EventBeginElement (streamP "stream")
378 [ attr "xmlns" namespace
379 , attr "version" "1.0"
380 ]
381 ]
382-}
383
384goodbye =
385 [ EventEndElement (streamP "stream")
386 , EventEndDocument
387 ]
388 365
389data XMPPState 366data XMPPState
390 = PingSlot 367 = PingSlot
@@ -407,6 +384,7 @@ makePing namespace mid to from =
407 , EventEndElement $ mkname namespace "iq"] 384 , EventEndElement $ mkname namespace "iq"]
408 385
409makePong namespace mid to from = 386makePong namespace mid to from =
387 -- Note: similar to session reply
410 [ EventBeginElement (mkname namespace "iq") 388 [ EventBeginElement (mkname namespace "iq")
411 $(case mid of 389 $(case mid of
412 Just c -> (("id",[ContentText c]):) 390 Just c -> (("id",[ContentText c]):)
@@ -418,6 +396,56 @@ makePong namespace mid to from =
418 , EventEndElement (mkname namespace "iq") 396 , EventEndElement (mkname namespace "iq")
419 ] 397 ]
420 398
399iq_bind_reply :: Maybe Text -> Text -> [XML.Event]
400iq_bind_reply mid jid =
401 [ EventBeginElement "{jabber:client}iq" (consid mid [("type",[ContentText "result"])])
402 , EventBeginElement "{urn:ietf:params:xml:ns:xmpp-bind}bind"
403 [("xmlns",[ContentText "urn:ietf:params:xml:ns:xmpp-bind"])]
404 , EventBeginElement "{urn:ietf:params:xml:ns:xmpp-bind}jid" []
405 , EventContent (ContentText jid)
406 , EventEndElement "{urn:ietf:params:xml:ns:xmpp-bind}jid"
407 , EventEndElement "{urn:ietf:params:xml:ns:xmpp-bind}bind"
408 , EventEndElement "{jabber:client}iq"
409 ]
410
411iq_session_reply mid host =
412 -- Note: similar to Pong
413 [ EventBeginElement "{jabber:client}iq"
414 (consid mid [("from",[ContentText host])
415 ,("type",[ContentText "result"])
416 ])
417 , EventEndElement "{jabber:client}iq"
418 ]
419
420iq_service_unavailable mid host {- mjid -} req =
421 [ EventBeginElement "{jabber:client}iq"
422 (consid mid [("type",[ContentText "error"])
423 -- , TODO: set "from" if isJust mjid
424 ])
425 , EventBeginElement req []
426 , EventEndElement req
427 , EventBeginElement "{jabber:client}error" [("type",[ContentText "cancel"])]
428 , EventBeginElement "{urn:ietf:params:xml:ns:xmpp-stanzas}service-unavailable" []
429 , EventEndElement "{urn:ietf:params:xml:ns:xmpp-stanzas}service-unavailable"
430 , EventEndElement "{jabber:client}error"
431 , EventEndElement "{jabber:client}iq"
432 ]
433
434
435{-
436greet namespace =
437 [ EventBeginDocument
438 , EventBeginElement (streamP "stream")
439 [ attr "xmlns" namespace
440 , attr "version" "1.0"
441 ]
442 ]
443-}
444
445goodbye =
446 [ EventEndElement (streamP "stream")
447 , EventEndDocument
448 ]
421 449
422forkConnection :: Server ConnectionKey 450forkConnection :: Server ConnectionKey
423 -> ConnectionKey 451 -> ConnectionKey
@@ -569,14 +597,23 @@ monitor sv params = do
569 _ -> return () 597 _ -> return ()
570 , readTChan stanzas >>= \stanza -> return $ do 598 , readTChan stanzas >>= \stanza -> return $ do
571 forkIO $ do 599 forkIO $ do
572 case (stanzaType stanza,stanzaOrigin stanza) of 600 case stanzaOrigin stanza of
573 (RequestResource wanted, NetworkOrigin k@(ClientKey{}) replyto) -> do 601 NetworkOrigin k@(ClientKey {}) replyto ->
574 sock <- socketFromKey sv k 602 case stanzaType stanza of
575 rsc <- getResourceName sock wanted 603 RequestResource wanted -> do
576 let reply = iq_bind_reply (stanzaId stanza) rsc 604 sock <- socketFromKey sv k
577 sendReply quitVar SetResource reply replyto 605 rsc <- getResourceName sock wanted
606 let reply = iq_bind_reply (stanzaId stanza) rsc
607 sendReply quitVar SetResource reply replyto
608 SessionRequest -> do
609 let reply = iq_session_reply (stanzaId stanza) "localhost"
610 sendReply quitVar Pong reply replyto
611 UnrecognizedQuery query -> do
612 let reply = iq_service_unavailable (stanzaId stanza) "localhost" query
613 sendReply quitVar Error reply replyto
614 _ -> return ()
578 _ -> return () 615 _ -> return ()
579 let typ = Strict8.pack $ c ++ "->"++(show (stanzaType stanza))++" " 616 let typ = Strict8.pack $ c ++ "->"++(concat . take 1 . words $ show (stanzaType stanza))++" "
580 c = case stanzaOrigin stanza of 617 c = case stanzaOrigin stanza of
581 LocalPeer -> "*" 618 LocalPeer -> "*"
582 NetworkOrigin (ClientKey {}) _ -> "C" 619 NetworkOrigin (ClientKey {}) _ -> "C"