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.
67 lines
2.5 KiB
67 lines
2.5 KiB
|
14 years ago
|
{-# LANGUAGE NoMonomorphismRestriction, OverloadedStrings #-}
|
||
|
14 years ago
|
|
||
|
14 years ago
|
module Network.Xmpp.Sasl where
|
||
|
14 years ago
|
|
||
|
14 years ago
|
import Control.Applicative
|
||
|
14 years ago
|
import Control.Arrow (left)
|
||
|
14 years ago
|
import Control.Monad
|
||
|
14 years ago
|
import Control.Monad.Error
|
||
|
14 years ago
|
import Control.Monad.State.Strict
|
||
|
14 years ago
|
import Data.Maybe (fromJust, isJust)
|
||
|
14 years ago
|
|
||
|
|
import qualified Crypto.Classes as CC
|
||
|
|
|
||
|
|
import qualified Data.Binary as Binary
|
||
|
14 years ago
|
import qualified Data.ByteString.Base64 as B64
|
||
|
14 years ago
|
import qualified Data.ByteString.Char8 as BS8
|
||
|
|
import qualified Data.ByteString.Lazy as BL
|
||
|
|
import qualified Data.Digest.Pure.MD5 as MD5
|
||
|
14 years ago
|
import qualified Data.List as L
|
||
|
14 years ago
|
import Data.Word (Word8)
|
||
|
14 years ago
|
|
||
|
|
import qualified Data.Text as Text
|
||
|
14 years ago
|
import Data.Text (Text)
|
||
|
14 years ago
|
import qualified Data.Text.Encoding as Text
|
||
|
|
|
||
|
14 years ago
|
import Network.Xmpp.Monad
|
||
|
|
import Network.Xmpp.Stream
|
||
|
|
import Network.Xmpp.Types
|
||
|
|
import Network.Xmpp.Pickle
|
||
|
14 years ago
|
|
||
|
|
import qualified System.Random as Random
|
||
|
|
|
||
|
14 years ago
|
import Network.Xmpp.Sasl.Sasl
|
||
|
|
import Network.Xmpp.Sasl.DigestMD5
|
||
|
|
import Network.Xmpp.Sasl.Plain
|
||
|
|
import Network.Xmpp.Sasl.Types
|
||
|
14 years ago
|
|
||
|
14 years ago
|
-- Uses the first supported mechanism to authenticate, if any. Updates the
|
||
|
14 years ago
|
-- XmppConMonad state with non-password credentials and restarts the stream upon
|
||
|
14 years ago
|
-- success. This computation wraps an ErrorT computation, which means that
|
||
|
|
-- catchError can be used to catch any errors.
|
||
|
14 years ago
|
xmppSASL :: [SASLCredentials] -- ^ Acceptable authentication mechanisms and
|
||
|
|
-- their corresponding credentials
|
||
|
14 years ago
|
-> XmppConMonad (Either AuthError ())
|
||
|
14 years ago
|
xmppSASL creds = runErrorT $ do
|
||
|
|
-- Chooses the first mechanism that is acceptable by both the client and the
|
||
|
|
-- server.
|
||
|
|
mechanisms <- gets $ saslMechanisms . sFeatures
|
||
|
|
let cred = L.find (\cred -> credsToName cred `elem` mechanisms) creds
|
||
|
|
unless (isJust cred) (throwError $ AuthMechanismError mechanisms)
|
||
|
|
case fromJust cred of
|
||
|
14 years ago
|
DIGEST_MD5Credentials authzid authcid passwd -> ErrorT $ xmppDigestMD5
|
||
|
14 years ago
|
authzid
|
||
|
|
authcid
|
||
|
|
passwd
|
||
|
14 years ago
|
PLAINCredentials authzid authcid passwd -> ErrorT $ xmppPLAIN
|
||
|
|
authzid
|
||
|
|
authcid
|
||
|
|
passwd
|
||
|
14 years ago
|
_ -> error "xmppSASL: Mechanism not caught"
|
||
|
14 years ago
|
where
|
||
|
14 years ago
|
-- Converts the credentials to the appropriate mechanism name, corresponding to
|
||
|
|
-- the XMPP mechanism attribute.
|
||
|
|
credsToName :: SASLCredentials -> Text
|
||
|
|
credsToName (DIGEST_MD5Credentials _ _ _) = "DIGEST-MD5"
|
||
|
14 years ago
|
credsToName (PLAINCredentials _ _ _) = "PLAIN"
|
||
|
14 years ago
|
credsToName c = error $ "credsToName failed for " ++ (show c)
|