You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
73 lines
2.4 KiB
73 lines
2.4 KiB
|
14 years ago
|
{-# LANGUAGE OverloadedStrings #-}
|
||
|
|
|
||
|
14 years ago
|
module Network.Xmpp.Sasl.Common where
|
||
|
14 years ago
|
|
||
|
14 years ago
|
import Network.Xmpp.Types
|
||
|
14 years ago
|
|
||
|
14 years ago
|
import Control.Applicative ((<$>))
|
||
|
14 years ago
|
import Control.Monad.Error
|
||
|
14 years ago
|
|
||
|
14 years ago
|
import qualified Data.Attoparsec.ByteString.Char8 as AP
|
||
|
14 years ago
|
import qualified Data.ByteString as BS
|
||
|
|
import Data.Maybe (fromMaybe)
|
||
|
|
import Data.Maybe (maybeToList)
|
||
|
|
import Data.Text
|
||
|
14 years ago
|
import Data.XML.Pickle
|
||
|
|
import Data.XML.Types
|
||
|
|
|
||
|
14 years ago
|
import Network.Xmpp.Pickle
|
||
|
14 years ago
|
|
||
|
14 years ago
|
-- The <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/> element, with an
|
||
|
|
-- optional round-trip value.
|
||
|
|
saslInitE :: Text -> Maybe Text -> Element
|
||
|
|
saslInitE mechanism rt =
|
||
|
14 years ago
|
Element "{urn:ietf:params:xml:ns:xmpp-sasl}auth"
|
||
|
|
[("mechanism", [ContentText mechanism])]
|
||
|
14 years ago
|
(maybeToList $ NodeContent . ContentText <$> rt)
|
||
|
14 years ago
|
|
||
|
14 years ago
|
-- SASL response with text payload.
|
||
|
|
saslResponseE :: Text -> Element
|
||
|
|
saslResponseE resp =
|
||
|
|
Element "{urn:ietf:params:xml:ns:xmpp-sasl}response"
|
||
|
|
[]
|
||
|
|
[NodeContent $ ContentText resp]
|
||
|
14 years ago
|
|
||
|
14 years ago
|
-- SASL response without payload.
|
||
|
|
saslResponse2E :: Element
|
||
|
|
saslResponse2E =
|
||
|
|
Element "{urn:ietf:params:xml:ns:xmpp-sasl}response"
|
||
|
|
[]
|
||
|
|
[]
|
||
|
14 years ago
|
|
||
|
14 years ago
|
-- Parses the incoming SASL data to a mapped list of pairs.
|
||
|
|
toPairs :: BS.ByteString -> Either String [(BS.ByteString, BS.ByteString)]
|
||
|
|
toPairs = AP.parseOnly . flip AP.sepBy1 (void $ AP.char ',') $ do
|
||
|
|
AP.skipSpace
|
||
|
|
name <- AP.takeWhile1 (/= '=')
|
||
|
|
_ <- AP.char '='
|
||
|
|
quote <- ((AP.char '"' >> return True) `mplus` return False)
|
||
|
|
content <- AP.takeWhile1 (AP.notInClass [',', '"'])
|
||
|
|
when quote . void $ AP.char '"'
|
||
|
|
return (name, content)
|
||
|
|
|
||
|
|
-- Failure element pickler.
|
||
|
|
failurePickle :: PU [Node] SaslFailure
|
||
|
|
failurePickle = xpWrap
|
||
|
|
(\(txt, (failure, _, _)) -> SaslFailure failure txt)
|
||
|
|
(\(SaslFailure failure txt) -> (txt,(failure,(),())))
|
||
|
|
(xpElemNodes
|
||
|
|
"{urn:ietf:params:xml:ns:xmpp-sasl}failure"
|
||
|
|
(xp2Tuple
|
||
|
|
(xpOption $ xpElem
|
||
|
|
"{urn:ietf:params:xml:ns:xmpp-sasl}text"
|
||
|
|
xpLangTag
|
||
|
|
(xpContent xpId))
|
||
|
|
(xpElemByNamespace
|
||
|
|
"urn:ietf:params:xml:ns:xmpp-sasl"
|
||
|
|
xpPrim
|
||
|
|
(xpUnit)
|
||
|
|
(xpUnit))))
|
||
|
|
-- Challenge element pickler.
|
||
|
|
challengePickle :: PU [Node] Text
|
||
|
|
challengePickle = xpElemNodes "{urn:ietf:params:xml:ns:xmpp-sasl}challenge"
|
||
|
|
(xpIsolate $ xpContent xpId)
|