|
|
|
@ -36,7 +36,6 @@ import Data.XML.Pickle |
|
|
|
import Data.XML.Types |
|
|
|
import Data.XML.Types |
|
|
|
import qualified GHC.IO.Exception as GIE |
|
|
|
import qualified GHC.IO.Exception as GIE |
|
|
|
import Network |
|
|
|
import Network |
|
|
|
import Network.TLS |
|
|
|
|
|
|
|
import Network.DNS hiding (encode, lookup) |
|
|
|
import Network.DNS hiding (encode, lookup) |
|
|
|
import Network.Xmpp.Marshal |
|
|
|
import Network.Xmpp.Marshal |
|
|
|
import Network.Xmpp.Types |
|
|
|
import Network.Xmpp.Types |
|
|
|
@ -47,6 +46,7 @@ import System.Random (randomRIO) |
|
|
|
import Text.XML.Stream.Parse as XP |
|
|
|
import Text.XML.Stream.Parse as XP |
|
|
|
|
|
|
|
|
|
|
|
import Network.Xmpp.Utilities |
|
|
|
import Network.Xmpp.Utilities |
|
|
|
|
|
|
|
import qualified Network.Xmpp.Lens as L |
|
|
|
|
|
|
|
|
|
|
|
-- "readMaybe" definition, as readMaybe is not introduced in the `base' package |
|
|
|
-- "readMaybe" definition, as readMaybe is not introduced in the `base' package |
|
|
|
-- until version 4.6. |
|
|
|
-- until version 4.6. |
|
|
|
@ -518,10 +518,9 @@ createStream :: HostName -> StreamConfiguration -> ErrorT XmppFailure IO (Stream |
|
|
|
createStream realm config = do |
|
|
|
createStream realm config = do |
|
|
|
result <- connect realm config |
|
|
|
result <- connect realm config |
|
|
|
case result of |
|
|
|
case result of |
|
|
|
Just (host, hand) -> ErrorT $ do |
|
|
|
Just hand -> ErrorT $ do |
|
|
|
debugM "Pontarius.Xmpp" "Acquired handle." |
|
|
|
debugM "Pontarius.Xmpp" "Acquired handle." |
|
|
|
debugM "Pontarius.Xmpp" "Setting NoBuffering mode on handle." |
|
|
|
debugM "Pontarius.Xmpp" "Setting NoBuffering mode on handle." |
|
|
|
debugM "Pontarius.Xmpp" $ "Setting TLS expected host to " ++ show host |
|
|
|
|
|
|
|
eSource <- liftIO . bufferSrc $ |
|
|
|
eSource <- liftIO . bufferSrc $ |
|
|
|
(sourceStreamHandle hand $= logConduit) |
|
|
|
(sourceStreamHandle hand $= logConduit) |
|
|
|
$= XP.parseBytes def |
|
|
|
$= XP.parseBytes def |
|
|
|
@ -535,7 +534,7 @@ createStream realm config = do |
|
|
|
, streamId = Nothing |
|
|
|
, streamId = Nothing |
|
|
|
, streamLang = Nothing |
|
|
|
, streamLang = Nothing |
|
|
|
, streamJid = Nothing |
|
|
|
, streamJid = Nothing |
|
|
|
, streamConfiguration = setCertificateHost host config |
|
|
|
, streamConfiguration = maybeSetTlsHost realm config |
|
|
|
} |
|
|
|
} |
|
|
|
stream' <- mkStream stream |
|
|
|
stream' <- mkStream stream |
|
|
|
return $ Right stream' |
|
|
|
return $ Right stream' |
|
|
|
@ -548,17 +547,14 @@ createStream realm config = do |
|
|
|
liftIO . debugM "Pontarius.Xmpp" $ "In: " ++ (BSC8.unpack d) ++ |
|
|
|
liftIO . debugM "Pontarius.Xmpp" $ "In: " ++ (BSC8.unpack d) ++ |
|
|
|
"." |
|
|
|
"." |
|
|
|
return d |
|
|
|
return d |
|
|
|
setCertificateHost host conf = |
|
|
|
tlsIdentL = L.tlsParamsL . L.clientServerIdentificationL |
|
|
|
conf{tlsParams = |
|
|
|
updateHost host ("", _) = (host, "") |
|
|
|
(tlsParams conf){clientServerIdentification = |
|
|
|
updateHost _ hst = hst |
|
|
|
case clientServerIdentification(tlsParams conf) of |
|
|
|
maybeSetTlsHost host = L.modify tlsIdentL (updateHost host) |
|
|
|
(_, blob) -> (host, blob)}} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Connects using the specified method. Returns the Handle acquired, if any. |
|
|
|
-- Connects using the specified method. Returns the Handle acquired, if any. |
|
|
|
connect :: HostName |
|
|
|
connect :: HostName -> StreamConfiguration -> ErrorT XmppFailure IO |
|
|
|
-> StreamConfiguration |
|
|
|
(Maybe StreamHandle) |
|
|
|
-> ErrorT XmppFailure IO (Maybe (HostName, StreamHandle)) |
|
|
|
|
|
|
|
connect realm config = do |
|
|
|
connect realm config = do |
|
|
|
case connectionDetails config of |
|
|
|
case connectionDetails config of |
|
|
|
UseHost host port -> lift $ do |
|
|
|
UseHost host port -> lift $ do |
|
|
|
@ -568,26 +564,24 @@ connect realm config = do |
|
|
|
Nothing -> return Nothing |
|
|
|
Nothing -> return Nothing |
|
|
|
Just h' -> do |
|
|
|
Just h' -> do |
|
|
|
liftIO $ hSetBuffering h' NoBuffering |
|
|
|
liftIO $ hSetBuffering h' NoBuffering |
|
|
|
return . Just $ (host, handleToStreamHandle h') |
|
|
|
return . Just $ handleToStreamHandle h' |
|
|
|
UseSrv host -> do |
|
|
|
UseSrv host -> do |
|
|
|
h <- connectSrv (resolvConf config) host |
|
|
|
h <- connectSrv (resolvConf config) host |
|
|
|
case h of |
|
|
|
case h of |
|
|
|
Nothing -> return Nothing |
|
|
|
Nothing -> return Nothing |
|
|
|
Just (hn, h') -> do |
|
|
|
Just h' -> do |
|
|
|
liftIO $ hSetBuffering h' NoBuffering |
|
|
|
liftIO $ hSetBuffering h' NoBuffering |
|
|
|
return . Just $ (hn, handleToStreamHandle h') |
|
|
|
return . Just $ handleToStreamHandle h' |
|
|
|
UseRealm -> do |
|
|
|
UseRealm -> do |
|
|
|
h <- connectSrv (resolvConf config) realm |
|
|
|
h <- connectSrv (resolvConf config) realm |
|
|
|
case h of |
|
|
|
case h of |
|
|
|
Nothing -> return Nothing |
|
|
|
Nothing -> return Nothing |
|
|
|
Just (hn, h') -> do |
|
|
|
Just h' -> do |
|
|
|
liftIO $ hSetBuffering h' NoBuffering |
|
|
|
liftIO $ hSetBuffering h' NoBuffering |
|
|
|
return $ Just (hn, handleToStreamHandle h') |
|
|
|
return . Just $ handleToStreamHandle h' |
|
|
|
UseConnection mkC -> Just <$> mkC |
|
|
|
UseConnection mkC -> Just <$> mkC |
|
|
|
|
|
|
|
|
|
|
|
connectSrv :: ResolvConf |
|
|
|
connectSrv :: ResolvConf -> String -> ErrorT XmppFailure IO (Maybe Handle) |
|
|
|
-> String |
|
|
|
|
|
|
|
-> ErrorT XmppFailure IO (Maybe (HostName, Handle)) |
|
|
|
|
|
|
|
connectSrv config host = do |
|
|
|
connectSrv config host = do |
|
|
|
case checkHostName (Text.pack host) of |
|
|
|
case checkHostName (Text.pack host) of |
|
|
|
Just host' -> do |
|
|
|
Just host' -> do |
|
|
|
@ -598,9 +592,8 @@ connectSrv config host = do |
|
|
|
Nothing -> do |
|
|
|
Nothing -> do |
|
|
|
lift $ debugM "Pontarius.Xmpp" |
|
|
|
lift $ debugM "Pontarius.Xmpp" |
|
|
|
"No SRV records, using fallback process." |
|
|
|
"No SRV records, using fallback process." |
|
|
|
h <- lift $ resolvAndConnectTcp resolvSeed (BSC8.pack $ host) |
|
|
|
lift $ resolvAndConnectTcp resolvSeed (BSC8.pack $ host) |
|
|
|
5222 |
|
|
|
5222 |
|
|
|
return $ (\h' -> (host, h')) <$> h |
|
|
|
|
|
|
|
Just srvRecords' -> do |
|
|
|
Just srvRecords' -> do |
|
|
|
lift $ debugM "Pontarius.Xmpp" |
|
|
|
lift $ debugM "Pontarius.Xmpp" |
|
|
|
"SRV records found, performing A/AAAA lookups." |
|
|
|
"SRV records found, performing A/AAAA lookups." |
|
|
|
@ -681,17 +674,12 @@ resolvAndConnectTcp resolvSeed domain port = do |
|
|
|
|
|
|
|
|
|
|
|
-- Tries `resolvAndConnectTcp' for every SRV record, stopping if a handle is |
|
|
|
-- Tries `resolvAndConnectTcp' for every SRV record, stopping if a handle is |
|
|
|
-- acquired. |
|
|
|
-- acquired. |
|
|
|
resolvSrvsAndConnectTcp :: ResolvSeed |
|
|
|
resolvSrvsAndConnectTcp :: ResolvSeed -> [(Domain, Int)] -> IO (Maybe Handle) |
|
|
|
-> [(Domain, Int)] |
|
|
|
|
|
|
|
-> IO (Maybe (HostName, Handle)) |
|
|
|
|
|
|
|
resolvSrvsAndConnectTcp _ [] = return Nothing |
|
|
|
resolvSrvsAndConnectTcp _ [] = return Nothing |
|
|
|
resolvSrvsAndConnectTcp resolvSeed ((domain, port):remaining) = do |
|
|
|
resolvSrvsAndConnectTcp resolvSeed ((domain, port):remaining) = do |
|
|
|
result <- resolvAndConnectTcp resolvSeed domain port |
|
|
|
result <- resolvAndConnectTcp resolvSeed domain port |
|
|
|
case result of |
|
|
|
case result of |
|
|
|
-- The last character of the target is always a dot in SRV records, so |
|
|
|
Just handle -> return $ Just handle |
|
|
|
-- we drop it. (Presumably the dns library should do that?) |
|
|
|
|
|
|
|
Just handle -> return $ Just ( init . Text.unpack $ Text.decodeUtf8 $ domain |
|
|
|
|
|
|
|
, handle) |
|
|
|
|
|
|
|
Nothing -> resolvSrvsAndConnectTcp resolvSeed remaining |
|
|
|
Nothing -> resolvSrvsAndConnectTcp resolvSeed remaining |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|