|
|
|
@ -18,7 +18,7 @@ import Data.XML.Types |
|
|
|
import Network.TLS |
|
|
|
import Network.TLS |
|
|
|
import Network.Xmpp.Stream |
|
|
|
import Network.Xmpp.Stream |
|
|
|
import Network.Xmpp.Types |
|
|
|
import Network.Xmpp.Types |
|
|
|
import System.Log.Logger (debugM, errorM) |
|
|
|
import System.Log.Logger (debugM, errorM, infoM) |
|
|
|
|
|
|
|
|
|
|
|
mkBackend :: StreamHandle -> Backend |
|
|
|
mkBackend :: StreamHandle -> Backend |
|
|
|
mkBackend con = Backend { backendSend = \bs -> void (streamSend con bs) |
|
|
|
mkBackend con = Backend { backendSend = \bs -> void (streamSend con bs) |
|
|
|
@ -51,27 +51,29 @@ tls con = Ex.handle (return . Left . TlsError) |
|
|
|
case sState of |
|
|
|
case sState of |
|
|
|
Plain -> return () |
|
|
|
Plain -> return () |
|
|
|
Closed -> do |
|
|
|
Closed -> do |
|
|
|
liftIO $ errorM "Pontarius.XMPP" "startTls: The stream is closed." |
|
|
|
liftIO $ errorM "Pontarius.Xmpp" "startTls: The stream is closed." |
|
|
|
throwError XmppNoStream |
|
|
|
throwError XmppNoStream |
|
|
|
Secured -> do |
|
|
|
Secured -> do |
|
|
|
liftIO $ errorM "Pontarius.XMPP" "startTls: The stream is already secured." |
|
|
|
liftIO $ errorM "Pontarius.Xmpp" "startTls: The stream is already secured." |
|
|
|
throwError TlsStreamSecured |
|
|
|
throwError TlsStreamSecured |
|
|
|
features <- lift $ gets streamFeatures |
|
|
|
features <- lift $ gets streamFeatures |
|
|
|
case (tlsBehaviour conf, streamTls features) of |
|
|
|
case (tlsBehaviour conf, streamTls features) of |
|
|
|
(RequireTls , Just _ ) -> startTls |
|
|
|
(RequireTls , Just _ ) -> startTls |
|
|
|
(RequireTls , Nothing ) -> throwError TlsNoServerSupport |
|
|
|
(RequireTls , Nothing ) -> throwError TlsNoServerSupport |
|
|
|
(PreferTls , Just _ ) -> startTls |
|
|
|
(PreferTls , Just _ ) -> startTls |
|
|
|
(PreferTls , Nothing ) -> return () |
|
|
|
(PreferTls , Nothing ) -> skipTls |
|
|
|
(PreferPlain , Just True) -> startTls |
|
|
|
(PreferPlain , Just True) -> startTls |
|
|
|
(PreferPlain , _ ) -> return () |
|
|
|
(PreferPlain , _ ) -> skipTls |
|
|
|
(RefuseTls , Just True) -> throwError XmppOtherFailure |
|
|
|
(RefuseTls , Just True) -> throwError XmppOtherFailure |
|
|
|
(RefuseTls , _ ) -> return () |
|
|
|
(RefuseTls , _ ) -> skipTls |
|
|
|
where |
|
|
|
where |
|
|
|
|
|
|
|
skipTls = liftIO $ infoM "Pontarius.Xmpp" "Skipping TLS negotiation" |
|
|
|
startTls = do |
|
|
|
startTls = do |
|
|
|
|
|
|
|
liftIO $ infoM "Pontarius.Xmpp" "Running StartTLS" |
|
|
|
params <- gets $ tlsParams . streamConfiguration |
|
|
|
params <- gets $ tlsParams . streamConfiguration |
|
|
|
sent <- ErrorT $ pushElement starttlsE |
|
|
|
sent <- ErrorT $ pushElement starttlsE |
|
|
|
unless sent $ do |
|
|
|
unless sent $ do |
|
|
|
liftIO $ errorM "Pontarius.XMPP" "startTls: Could not sent stanza." |
|
|
|
liftIO $ errorM "Pontarius.Xmpp" "startTls: Could not sent stanza." |
|
|
|
throwError XmppOtherFailure |
|
|
|
throwError XmppOtherFailure |
|
|
|
answer <- lift $ pullElement |
|
|
|
answer <- lift $ pullElement |
|
|
|
case answer of |
|
|
|
case answer of |
|
|
|
@ -79,10 +81,10 @@ tls con = Ex.handle (return . Left . TlsError) |
|
|
|
Right (Element "{urn:ietf:params:xml:ns:xmpp-tls}proceed" [] []) -> |
|
|
|
Right (Element "{urn:ietf:params:xml:ns:xmpp-tls}proceed" [] []) -> |
|
|
|
return () |
|
|
|
return () |
|
|
|
Right (Element "{urn:ietf:params:xml:ns:xmpp-tls}failure" _ _) -> do |
|
|
|
Right (Element "{urn:ietf:params:xml:ns:xmpp-tls}failure" _ _) -> do |
|
|
|
liftIO $ errorM "Pontarius.XMPP" "startTls: TLS initiation failed." |
|
|
|
liftIO $ errorM "Pontarius.Xmpp" "startTls: TLS initiation failed." |
|
|
|
throwError XmppOtherFailure |
|
|
|
throwError XmppOtherFailure |
|
|
|
Right r -> |
|
|
|
Right r -> |
|
|
|
liftIO $ errorM "Pontarius.XMPP" $ |
|
|
|
liftIO $ errorM "Pontarius.Xmpp" $ |
|
|
|
"startTls: Unexpected element: " ++ show r |
|
|
|
"startTls: Unexpected element: " ++ show r |
|
|
|
hand <- gets streamHandle |
|
|
|
hand <- gets streamHandle |
|
|
|
(_raw, _snk, psh, recv, ctx) <- lift $ tlsinit params (mkBackend hand) |
|
|
|
(_raw, _snk, psh, recv, ctx) <- lift $ tlsinit params (mkBackend hand) |
|
|
|
@ -92,6 +94,7 @@ tls con = Ex.handle (return . Left . TlsError) |
|
|
|
, streamClose = bye ctx >> streamClose hand |
|
|
|
, streamClose = bye ctx >> streamClose hand |
|
|
|
} |
|
|
|
} |
|
|
|
lift $ modify ( \x -> x {streamHandle = newHand}) |
|
|
|
lift $ modify ( \x -> x {streamHandle = newHand}) |
|
|
|
|
|
|
|
liftIO $ infoM "Pontarius.Xmpp" "Stream Secured." |
|
|
|
either (lift . Ex.throwIO) return =<< lift restartStream |
|
|
|
either (lift . Ex.throwIO) return =<< lift restartStream |
|
|
|
modify (\s -> s{streamConnectionState = Secured}) |
|
|
|
modify (\s -> s{streamConnectionState = Secured}) |
|
|
|
return () |
|
|
|
return () |
|
|
|
@ -127,15 +130,11 @@ tlsinit params backend = do |
|
|
|
Nothing -> return () |
|
|
|
Nothing -> return () |
|
|
|
Just x -> do |
|
|
|
Just x -> do |
|
|
|
sendData con (BL.fromChunks [x]) |
|
|
|
sendData con (BL.fromChunks [x]) |
|
|
|
liftIO $ debugM "Pontarius.Xmpp.TLS" |
|
|
|
|
|
|
|
("out :" ++ BSC8.unpack x) |
|
|
|
|
|
|
|
snk |
|
|
|
snk |
|
|
|
readWithBuffer <- liftIO $ mkReadBuffer (recvData con) |
|
|
|
readWithBuffer <- liftIO $ mkReadBuffer (recvData con) |
|
|
|
return ( src |
|
|
|
return ( src |
|
|
|
, snk |
|
|
|
, snk |
|
|
|
, \s -> do |
|
|
|
, \s -> sendData con $ BL.fromChunks [s] |
|
|
|
liftIO $ debugM "Pontarius.Xmpp.TLS" ("out :" ++ BSC8.unpack s) |
|
|
|
|
|
|
|
sendData con $ BL.fromChunks [s] |
|
|
|
|
|
|
|
, liftIO . readWithBuffer |
|
|
|
, liftIO . readWithBuffer |
|
|
|
, con |
|
|
|
, con |
|
|
|
) |
|
|
|
) |
|
|
|
|