packages feed

xml-push 0.0.0.10 → 0.0.0.11

raw patch · 6 files changed

+329/−4 lines, 6 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Network.XmlPush.Xmpp.Server: XmppServerArgs :: ByteString -> [(ByteString, ByteString)] -> (XmlNode -> Bool) -> (XmlNode -> Bool) -> XmppServerArgs h
+ Network.XmlPush.Xmpp.Server: data XmppServer h
+ Network.XmlPush.Xmpp.Server: data XmppServerArgs h
+ Network.XmlPush.Xmpp.Server: domainName :: XmppServerArgs h -> ByteString
+ Network.XmlPush.Xmpp.Server: iNeedResponse :: XmppServerArgs h -> XmlNode -> Bool
+ Network.XmlPush.Xmpp.Server: instance XmlPusher XmppServer
+ Network.XmlPush.Xmpp.Server: passwords :: XmppServerArgs h -> [(ByteString, ByteString)]
+ Network.XmlPush.Xmpp.Server: youNeedResponse :: XmppServerArgs h -> XmlNode -> Bool
+ Network.XmlPush.Xmpp.Tls.Server: TlsArgs :: (XmlNode -> Maybe String) -> (XmlNode -> Maybe (SignedCertificate -> Bool)) -> [CipherSuite] -> Maybe CertificateStore -> [(CertSecretKey, CertificateChain)] -> TlsArgs
+ Network.XmlPush.Xmpp.Tls.Server: XmppServerArgs :: ByteString -> [(ByteString, ByteString)] -> (XmlNode -> Bool) -> (XmlNode -> Bool) -> XmppServerArgs h
+ Network.XmlPush.Xmpp.Tls.Server: XmppTlsServerArgs :: (XmppServerArgs h) -> TlsArgs -> XmppTlsServerArgs h
+ Network.XmlPush.Xmpp.Tls.Server: certificateAuthorities :: TlsArgs -> Maybe CertificateStore
+ Network.XmlPush.Xmpp.Tls.Server: checkCertificate :: TlsArgs -> XmlNode -> Maybe (SignedCertificate -> Bool)
+ Network.XmlPush.Xmpp.Tls.Server: cipherSuites :: TlsArgs -> [CipherSuite]
+ Network.XmlPush.Xmpp.Tls.Server: data TlsArgs
+ Network.XmlPush.Xmpp.Tls.Server: data XmppServerArgs h
+ Network.XmlPush.Xmpp.Tls.Server: data XmppTlsServer h
+ Network.XmlPush.Xmpp.Tls.Server: data XmppTlsServerArgs h
+ Network.XmlPush.Xmpp.Tls.Server: domainName :: XmppServerArgs h -> ByteString
+ Network.XmlPush.Xmpp.Tls.Server: getClientName :: TlsArgs -> XmlNode -> Maybe String
+ Network.XmlPush.Xmpp.Tls.Server: iNeedResponse :: XmppServerArgs h -> XmlNode -> Bool
+ Network.XmlPush.Xmpp.Tls.Server: instance XmlPusher XmppTlsServer
+ Network.XmlPush.Xmpp.Tls.Server: keyChains :: TlsArgs -> [(CertSecretKey, CertificateChain)]
+ Network.XmlPush.Xmpp.Tls.Server: passwords :: XmppServerArgs h -> [(ByteString, ByteString)]
+ Network.XmlPush.Xmpp.Tls.Server: youNeedResponse :: XmppServerArgs h -> XmlNode -> Bool
- Network.XmlPush: generate :: (XmlPusher xp, ValidateHandle h, MonadBaseControl IO (HandleMonad h), MonadError (HandleMonad h), Error (ErrorType (HandleMonad h))) => NumOfHandle xp h -> PusherArgs xp h -> HandleMonad h (xp h)
+ Network.XmlPush: generate :: (XmlPusher xp, ValidateHandle h, MonadBaseControl IO (HandleMonad h), MonadError (HandleMonad h), SaslError (ErrorType (HandleMonad h))) => NumOfHandle xp h -> PusherArgs xp h -> HandleMonad h (xp h)

Files

src/Network/XmlPush.hs view
@@ -9,13 +9,14 @@ import Data.Pipe import Text.XML.Pipe import Network.PeyoTLS.Client+import Network.Sasl  class XmlPusher xp where 	type NumOfHandle xp :: * -> * 	type PusherArgs xp :: * -> * 	generate :: ( 		ValidateHandle h, MonadBaseControl IO (HandleMonad h),-		MonadError (HandleMonad h), Error (ErrorType (HandleMonad h))+		MonadError (HandleMonad h), SaslError (ErrorType (HandleMonad h)) 		) => 		NumOfHandle xp h -> PusherArgs xp h -> HandleMonad h (xp h) 	readFrom :: (HandleLike h, MonadBase IO (HandleMonad h)) =>
src/Network/XmlPush/Xmpp.hs view
@@ -57,7 +57,7 @@ 		(Jid un d (Just rsc)) = me 		ss = St [ 			("username", un), ("authcid", un), ("password", ps),-			("cnonce", cn) ]+			("cnonce", cn), ("nc", "00000001"), ("uri", "hoge") ] 	void . (`evalStateT` ss) . runPipe $ fromHandleLike (THandle h) 		=$= sasl d ms 		=$= toHandleLike (THandle h)
+ src/Network/XmlPush/Xmpp/Server.hs view
@@ -0,0 +1,66 @@+{-# LANGUAGE+	PatternGuards,+	OverloadedStrings, TypeFamilies, FlexibleContexts,+	PackageImports #-}++module Network.XmlPush.Xmpp.Server (+	XmppServer, XmppServerArgs(..),+	) where++import Prelude hiding (filter)++import "monads-tf" Control.Monad.State+import "monads-tf" Control.Monad.Error+import Control.Monad.Base+import Control.Concurrent.STM+import Data.Maybe+import Data.HandleLike+import Data.Pipe+import Data.Pipe.Flow+import Data.Pipe.IO+import Text.XML.Pipe+import Network.XMPiPe.Core.C2S.Server+import Network.Sasl++import Network.XmlPush+import Network.XmlPush.Xmpp.Common+import Network.XmlPush.Xmpp.Server.Common++data XmppServer h = XmppServer+	(Pipe () XmlNode (HandleMonad h) ())+	(Pipe XmlNode () (HandleMonad h) ())++instance XmlPusher XmppServer where+	type NumOfHandle XmppServer = One+	type PusherArgs XmppServer = XmppServerArgs+	generate = makeXmppServer+	readFrom (XmppServer r _) = r+	writeTo (XmppServer _ w) = w++makeXmppServer :: (+	HandleLike h,+	MonadError (HandleMonad h), SaslError (ErrorType (HandleMonad h)),+	MonadBase IO (HandleMonad h) ) =>+	One h -> XmppServerArgs h -> HandleMonad h (XmppServer h)+makeXmppServer (One h) (XmppServerArgs dn ps inr ynr) = do+	rids <- liftBase $ atomically newTChan+	(Just ns, st) <- (`runStateT` initXSt dn) . runPipe $ do+		fromHandleLike (THandle h)+			=$= sasl dn (retrieves dn ps)+			=$= toHandleLike (THandle h)+		fromHandleLike (THandle h)+			=$= bind dn []+			=@= toHandleLike (THandle h)+	liftBase . print $ user st+	let	r = fromHandleLike h+			=$= input ns+			=$= debug+			=$= setIds h ynr rids+			=$= convert fromMessage+			=$= filter isJust+			=$= convert fromJust+		w = makeMpi (user st) inr rids+			=$= debug+			=$= output+			=$= toHandleLike h+	return $ XmppServer r w
+ src/Network/XmlPush/Xmpp/Server/Common.hs view
@@ -0,0 +1,153 @@+{-# LANGUAGE+ 	PatternGuards,+ 	OverloadedStrings, FlexibleContexts, PackageImports #-}++module Network.XmlPush.Xmpp.Server.Common (+	XmppServerArgs(..),+	retrieves,+	initXSt, user,+	setIds,+	makeMpi,+	) where++import "monads-tf" Control.Monad.State+import "monads-tf" Control.Monad.Error+import Control.Monad.Base+import Control.Concurrent.STM+import Data.Maybe+import Data.HandleLike+import Data.Pipe+import Data.Pipe.IO+import Data.UUID+import System.Random+import Text.XML.Pipe+import Network.XMPiPe.Core.C2S.Server+import Network.XMPiPe.Core.C2S.Client (toJid)+import Network.Sasl++import qualified Data.ByteString as BS+import qualified Network.Sasl.DigestMd5.Server as DM5+import qualified Network.Sasl.ScramSha1.Server as SS1++import Network.XmlPush.Xmpp.Common++data XmppServerArgs h = XmppServerArgs {+	domainName :: BS.ByteString,+	passwords :: [(BS.ByteString, BS.ByteString)],+	iNeedResponse :: XmlNode -> Bool,+	youNeedResponse :: XmlNode -> Bool+	}++retrieves :: (+	MonadState m, SaslState (StateType m),+	MonadError m, SaslError (ErrorType m) ) =>+	BS.ByteString -> [(BS.ByteString, BS.ByteString)] -> [Retrieve m]+retrieves dn ps = [+	RTPlain $ retrievePln ps,+	RTDigestMd5 $ retrieveDM5 dn ps,+	RTScramSha1 $ retrieveSS1 ps ]++retrievePln :: (+	MonadState m, SaslState (StateType m),+	MonadError m, SaslError (ErrorType m)) =>+	[(BS.ByteString, BS.ByteString)] ->+	BS.ByteString -> BS.ByteString -> BS.ByteString -> m ()+retrievePln ps "" usr pwd0+	| Just pwd <- lookup usr ps, pwd == pwd0 = return ()+retrievePln _ _ _ _ = throwError $ fromSaslError NotAuthorized "auth failure"++retrieveDM5 :: (+	MonadState m, SaslState (StateType m),+	MonadError m, SaslError (ErrorType m) ) =>+	BS.ByteString -> [(BS.ByteString, BS.ByteString)] ->+	BS.ByteString -> m BS.ByteString+retrieveDM5 dn ps usr+	| Just pwd <- lookup usr ps = return $ DM5.mkStored usr dn pwd+retrieveDM5 _ _ _ = throwError $ fromSaslError NotAuthorized "auth failure"++retrieveSS1 :: (+	MonadState m, SaslState (StateType m),+	MonadError m, SaslError (ErrorType m) ) =>+	[(BS.ByteString, BS.ByteString)] -> BS.ByteString ->+	m (BS.ByteString, BS.ByteString, BS.ByteString, Int)+retrieveSS1 ps usr | Just pwd <- lookup usr ps = let+	slt = "pepper"; i = 4492; (stk, svk) = SS1.salt pwd slt i in+	return (slt, stk, svk, i)+retrieveSS1 _ _ = throwError $ fromSaslError NotAuthorized "auth failure"++initXSt :: BS.ByteString -> XSt+initXSt dn = XSt {+	user = Jid "" dn Nothing, rands = repeat "00DEADBEEF00",+	sSt = [	("realm", dn), ("qop", "auth"), ("charset", "utf-8"),+		("algorithm", "md5-sess") ] }++type Pairs a = [(a, a)]+data XSt = XSt { user :: Jid, rands :: [BS.ByteString], sSt :: Pairs BS.ByteString }++instance XmppState XSt where+	getXmppState xs = (user xs, rands xs)+	putXmppState (usr, rl) xs = xs { user = usr, rands = rl }++instance SaslState XSt where+	getSaslState XSt { user = Jid n _ _, rands = nnc : _, sSt = ss } =+		("username", n) : ("nonce", nnc) : ("snonce", nnc) : ss+	getSaslState _ = error "XSt.getSaslState: null random list"+	putSaslState ss xs@XSt { user = Jid _ d r, rands = _ : rs } =+		xs { user = Jid n d r, rands = rs, sSt = ss }+		where Just n = lookup "username" ss+	putSaslState _ _ = error "XSt.getSaslState: null random list"++setIds :: (HandleLike h, MonadBase IO (HandleMonad h)) => h ->+	(XmlNode -> Bool) -> TChan BS.ByteString -> Pipe Mpi Mpi (HandleMonad h) ()+setIds h ynr rids = (await >>=) . maybe (return ()) $ \mpi -> do+	yield mpi+	if boolXmlNode ynr mpi+	then when (isGetSet mpi) . lift . liftBase . atomically+		$ writeTChan rids (fromJust $ getId mpi)+	else lift $ returnEmpty h "hoge"+	lift . liftBase . putStrLn $ "\nsetIds: " ++ show (getId mpi)+	setIds h ynr rids++isGetSet :: Mpi -> Bool+isGetSet (Iq Tags { tagType = Just "set" } _) = True+isGetSet (Iq Tags { tagType = Just "get" } _) = True+isGetSet _ = False++getId :: Mpi -> Maybe BS.ByteString+getId (Iq t _) = tagId t+getId (Message t _) = tagId t+getId _ = Nothing++boolXmlNode :: (XmlNode -> Bool) -> Mpi -> Bool+boolXmlNode f (Iq _ [n]) = f n+boolXmlNode _ _ = False++returnEmpty :: (HandleLike h, MonadBase IO (HandleMonad h)) => h -> BS.ByteString -> HandleMonad h ()+returnEmpty h i = runPipe_ $ yield e =$= output =$= debug =$= toHandleLike h+	where+	you = toJid "hoge@hogehost"+	e = Iq (tagsType "result") { tagId = Just i, tagTo = Just you } []++makeMpi :: MonadBase IO m => Jid ->+	(XmlNode -> Bool) -> TChan BS.ByteString -> Pipe XmlNode Mpi m ()+makeMpi usr inr rids = (await >>=) . maybe (return ()) $ \n -> do+	e <- lift . liftBase . atomically $ isEmptyTChan rids+	if e+	then if inr n+		then do	uuid <- lift $ liftBase randomIO+			yield $ Iq (tagsType "get") {+				tagId = Just $ toASCIIBytes uuid,+				tagTo = Just usr+				} [n]+		else do uuid <- lift $ liftBase randomIO+			yield $ Message (tagsType "chat") {+			tagId = Just $ toASCIIBytes uuid,+			tagTo = Just usr+			} [n]+	else do	i <- lift . liftBase .atomically $ readTChan rids+		lift . liftBase . putStrLn $ "makeMpi: " ++ show i+		yield $ Iq (tagsType "return") {+			tagId = Just i,+			tagTo = Just usr+			} [n]+	makeMpi usr inr rids
+ src/Network/XmlPush/Xmpp/Tls/Server.hs view
@@ -0,0 +1,103 @@+{-# LANGUAGE TypeFamilies, FlexibleContexts, ScopedTypeVariables,+	PackageImports #-}++module Network.XmlPush.Xmpp.Tls.Server (+	XmppTlsServer,+	XmppTlsServerArgs(..), XmppServerArgs(..), TlsArgs(..),+	) where++import Prelude hiding (filter)++import Control.Applicative+import "monads-tf" Control.Monad.State+import "monads-tf" Control.Monad.Error+import Control.Monad.Base+import Control.Monad.Trans.Control+import Control.Concurrent.STM+import Data.Maybe+import Data.HandleLike+import Data.Pipe+import Data.Pipe.Flow+import Data.Pipe.IO+import Data.Pipe.TChan+import Data.UUID+import Data.X509+import System.Random+import Text.XML.Pipe+import Network.XMPiPe.Core.C2S.Server+import Network.XmlPush+import Network.Sasl+import Network.PeyoTLS.TChan.Server+import "crypto-random" Crypto.Random++-- import qualified Data.ByteString.Char8 as BSC++import Network.XmlPush.Xmpp.Common+import Network.XmlPush.Xmpp.Server.Common+import Network.XmlPush.Tls.Server++data XmppTlsServer h = XmppTlsServer+	(Pipe () XmlNode (HandleMonad h) ())+	(Pipe XmlNode () (HandleMonad h) ())++data XmppTlsServerArgs h = XmppTlsServerArgs (XmppServerArgs h) TlsArgs++instance XmlPusher XmppTlsServer where+	type NumOfHandle XmppTlsServer = One+	type PusherArgs XmppTlsServer = XmppTlsServerArgs+	generate = makeXmppTlsServer+	readFrom (XmppTlsServer r _) = r+	writeTo (XmppTlsServer _ w) = w++makeXmppTlsServer :: (+	ValidateHandle h,+	MonadError (HandleMonad h), SaslError (ErrorType (HandleMonad h)),+	MonadBaseControl IO (HandleMonad h) ) =>+	One h -> XmppTlsServerArgs h -> HandleMonad h (XmppTlsServer h)+makeXmppTlsServer (One h) (XmppTlsServerArgs+	(XmppServerArgs dn ps inr ynr)+	(TlsArgs gn cc cs mca kcs)) = do+	rids <- liftBase $ atomically newTChan+	(g :: SystemRNG) <- liftBase $ cprgCreate <$> createEntropyPool+	us <- liftBase $ map toASCIIBytes . randoms <$> getStdGen+	_ <- (`execStateT` us) . runPipe_ $ fromHandleLike (THandle h)+		=$= starttls dn+		=$= toHandleLike (THandle h)+	(Just (cn, c), (inp, otp)) <- open h cs kcs mca g+	(Just ns, st) <- (`runStateT` initXSt dn) . runPipe $ do+		fromTChan inp =$= sasl dn (retrieves dn ps) =$= toTChan otp+		fromTChan inp =$= bind dn [] =@= toTChan otp+	liftBase . print $ user st+	let	r = fromTChan inp+			=$= input ns+			=$= debug+			=$= setIds h ynr rids+			=$= convert fromMessage+			=$= filter isJust+			=$= convert fromJust+			=$= checkName cn gn+			=$= checkCert c cc+		w = makeMpi (user st) inr rids+			=$= debug+			=$= output+			=$= toTChan otp+	return $ XmppTlsServer r w++checkName :: Monad m => (String -> Bool) -> (XmlNode -> Maybe String) ->+	Pipe XmlNode XmlNode m ()+checkName cn gn = (await >>=) . maybe (return ()) $ \nd -> do+	case gn nd of+		Just n -> unless (cn n) $ error "checkName: bad client name"+		_ -> return ()+	yield nd+	checkName cn gn++checkCert :: Monad m =>+	SignedCertificate -> (XmlNode -> Maybe (SignedCertificate -> Bool)) ->+	Pipe XmlNode XmlNode m ()+checkCert c cc = (await >>=) . maybe (return ()) $ \n -> do+	case cc n of+		Just ck -> unless (ck c) $ error "checkCert: bad certificate"+		_ -> return ()+	yield n+	checkCert c cc
xml-push.cabal view
@@ -2,7 +2,7 @@ cabal-version:	>= 1.8  name:		xml-push-version:	0.0.0.10+version:	0.0.0.11 stability:	Experimenmtal author:		Yoshikuni Jujo <PAF01143@nifty.ne.jp> maintainer:	Yoshikuni Jujo <PAF01143@nifty.ne.jp>@@ -100,13 +100,14 @@ source-repository	this     type:	git     location:	git://github.com/YoshikuniJujo/xml-push.git-    tag:	xml-push-0.0.0.10+    tag:	xml-push-0.0.0.11  library     hs-source-dirs:	src     exposed-modules:         Network.XmlPush, Network.XmlPush.Simple         Network.XmlPush.Xmpp, Network.XmlPush.Xmpp.Tls+        Network.XmlPush.Xmpp.Server, Network.XmlPush.Xmpp.Tls.Server,         Network.XmlPush.HttpPull.Client, Network.XmlPush.HttpPull.Server         Network.XmlPush.HttpPull.Tls.Client, Network.XmlPush.HttpPull.Tls.Server         Network.XmlPush.HttpPush, Network.XmlPush.HttpPush.Tls@@ -114,6 +115,7 @@         Network.XmlPush.Tls.Client         Network.XmlPush.Tls.Server         Network.XmlPush.Xmpp.Common+        Network.XmlPush.Xmpp.Server.Common         Network.XmlPush.HttpPull.Client.Common         Network.XmlPush.HttpPull.Server.Common         Network.XmlPush.HttpPush.Common