packages feed

network-simple-tls 0.3 → 0.3.1

raw patch · 3 files changed

+85/−24 lines, 3 filesdep +safe-exceptionsdep −exceptions

Dependencies added: safe-exceptions

Dependencies removed: exceptions

Files

changelog.md view
@@ -1,3 +1,11 @@+# Version 0.3.1++* Added SOCKS5 proxy support. See functions `connectOverSOCKS5` and+  `connectTlsOverSOCKS5`.++* Use `safe-exceptions`.++ # Version 0.3  * BREAKING CHANGE: Changed type of the following functions:
network-simple-tls.cabal view
@@ -1,5 +1,5 @@ name:                network-simple-tls-version:             0.3+version:             0.3.1 synopsis:            Simple interface to TLS secured network sockets. description:         Simple interface to TLS secured network sockets. homepage:            https://github.com/k0001/network-simple-tls@@ -23,15 +23,15 @@   exposed-modules:   Network.Simple.TCP.TLS   build-depends:     base              (>=4.5     && <5.0)                    , bytestring+                   , data-default                    , network-                   , exceptions                    , network-simple+                   , safe-exceptions                    , tls                    , transformers                    , x509-                   , x509-system                    , x509-store+                   , x509-system                    , x509-validation-                   , data-default   ghc-options:      -Wall -O2 
src/Network/Simple/TCP/TLS.hs view
@@ -10,7 +10,7 @@ -- in the @network-simple@ package. Consider using that module directly if you -- need a similar API without TLS support. ----- This module uses 'MonadIO' and 'C.MonadMask' extensively so that you can+-- This module uses 'MonadIO' and 'E.MonadMask' extensively so that you can -- reuse these functions in monads other than 'IO'. However, if you don't care -- about any of that, just pretend you are using the 'IO' monad all the time -- and everything will work as expected.@@ -31,6 +31,7 @@    -- * Client side   , connect+  , connectOverSOCKS5   -- ** Client TLS Settings   , ClientSettings   , makeClientSettings@@ -47,6 +48,7 @@   , useTlsThenClose   , useTlsThenCloseFork   , connectTls+  , connectTlsOverSOCKS5   , acceptTls   , makeClientContext   , makeServerContext@@ -64,9 +66,8 @@   import           Control.Concurrent (ThreadId, forkFinally)-import qualified Control.Exception as E+import qualified Control.Exception.Safe as E import           Control.Monad-import qualified Control.Monad.Catch as C import           Control.Monad.IO.Class (MonadIO, liftIO) import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as BL@@ -320,7 +321,7 @@ -- in case of exceptions. If you need to manage the lifetime of the connection -- resources yourself, then use 'acceptTls' instead. accept-  :: (MonadIO m, C.MonadMask m)+  :: (MonadIO m, E.MonadMask m)   => ServerSettings       -- ^TLS settings.   -> Socket               -- ^Listening and bound socket.   -> ((Context, SockAddr) -> m r)@@ -329,7 +330,7 @@                           -- TLS-secured communication is established. Takes the                           -- TLS connection context and remote end address.   -> m r-accept ss lsock k = C.bracket (acceptTls ss lsock)+accept ss lsock k = E.bracket (acceptTls ss lsock)                               (liftIO . T.contextClose . fst)                               (useTls k) @@ -359,19 +360,44 @@ -- in case of exceptions. If you need to manage the lifetime of the connection -- resources yourself, then use 'connectTls' instead. connect-  :: (MonadIO m, C.MonadMask m)-  => ClientSettings       -- ^TLS settings.-  -> HostName             -- ^Server hostname.-  -> ServiceName          -- ^Server service port.+  :: (MonadIO m, E.MonadMask m)+  => ClientSettings       -- ^ TLS settings.+  -> HostName             -- ^ Server hostname.+  -> ServiceName          -- ^ Destination server service port name or number.   -> ((Context, SockAddr) -> m r)-                          -- ^Computation to run after establishing TLS-secured-                          -- TCP connection to the remote server. Takes the TLS-                          -- connection context and remote end address.+  -- ^ Computation to run after establishing TLS-secured TCP connection to the+  -- remote server. Takes the TLS connection context and remote end address.   -> m r-connect cs host port k = C.bracket (connectTls cs host port)+connect cs host port k = E.bracket (connectTls cs host port)                                    (liftIO . T.contextClose . fst)                                    (useTls k) +-- | Like 'connect', but connects to the destination server over a SOCKS5 proxy.+connectOverSOCKS5+  :: (MonadIO m, E.MonadMask m)+  => HostName     -- ^ SOCKS5 proxy server hostname or IP address.+  -> ServiceName  -- ^ SOCKS5 proxy server service port name or number.+  -> ClientSettings  -- ^ TLS settings.+  -> HostName+  -- ^ Destination server hostname or IP address. We connect to this host+  -- /through/ the SOCKS5 proxy specified in the previous arguments.+  --+  -- Note that if hostname resolution on this 'HostName' is necessary, it+  -- will happen on the proxy side for security reasons, not locally.+  -> ServiceName -- ^ Destination server service port name or number.+  -> ((Context, SockAddr, SockAddr) -> m r)+  -- ^ Computation to run after establishing TLS-secured TCP connection to the+  -- remote server. Takes the TLS connection that can be used to interact with+  -- the destination server, as well as the address of the SOCKS5 server and the+  -- address of the destination server, in that order.+  -> m r+connectOverSOCKS5 phn psn cs dhn dsn k = do+  E.bracket (connectTlsOverSOCKS5 phn psn cs dhn dsn)+            (\(ctx, _, _) -> liftIO (T.contextClose ctx))+            (\(ctx, paddr, daddr) ->+                useTls (\_ -> k (ctx, paddr, daddr))+                       (ctx, paddr))+ --------------------------------------------------------------------------------  -- | Estalbishes a TCP connection to a remote server and returns a TLS@@ -387,9 +413,9 @@ -- 'useTlsThenCloseFork' can help you with that. connectTls   :: MonadIO m-  => ClientSettings       -- ^TLS settings.-  -> HostName             -- ^Server hostname.-  -> ServiceName          -- ^Service port to bind.+  => ClientSettings       -- ^ TLS settings.+  -> HostName             -- ^ Server hostname.+  -> ServiceName          -- ^ Server service name or port number.   -> m (Context, SockAddr) connectTls cs host port = liftIO $ do     E.bracketOnError@@ -399,6 +425,33 @@              ctx <- makeClientContext cs sock              return (ctx, addr)) +-- | Like 'connectTls', but connects to the destination server over a SOCKS5+-- proxy.+connectTlsOverSOCKS5+  :: MonadIO m+  => HostName     -- ^ SOCKS5 proxy server hostname or IP address.+  -> ServiceName  -- ^ SOCKS5 proxy server service port name or number.+  -> ClientSettings  -- ^ TLS settings.+  -> HostName+  -- ^ Destination server hostname or IP address. We connect to this host+  -- /through/ the SOCKS5 proxy specified in the previous arguments.+  --+  -- Note that if hostname resolution on this 'HostName' is necessary, it+  -- will happen on the proxy side for security reasons, not locally.+  -> ServiceName -- ^ Destination server service port name or number.+  -> m (Context, SockAddr, SockAddr)+  -- ^ Returns the 'Context' that can be used to interact with the destination+  -- server, as well as the address of the SOCKS5 server and the address of the+  -- destination server, in that order.+connectTlsOverSOCKS5 phn psn cs dhn dsn = liftIO $ do+  E.bracketOnError+     (S.connectSock phn psn)+     (S.closeSock . fst)+     (\(psock, paddr) -> do+          daddr <- S.connectSockSOCKS5 psock dhn dsn+          ctx <- makeClientContext cs psock+          return (ctx, paddr, daddr))+ -- | Make a client-side TLS 'Context' for the given settings, on top of the -- given TCP `Socket` connected to the remote end. makeClientContext :: MonadIO m => ClientSettings -> Socket -> m Context@@ -446,20 +499,20 @@ -- Prefer to use `useTlsThenClose` or `useTlsThenCloseFork` if you need that -- behavior. Otherwise, you must call `T.contextClose` yourself at some point. useTls-  :: (MonadIO m, C.MonadMask m)+  :: (MonadIO m, E.MonadMask m)   => ((Context, SockAddr) -> m a)   -> ((Context, SockAddr) -> m a)-useTls k conn@(ctx,_) = C.bracket_ (T.handshake ctx)+useTls k conn@(ctx,_) = E.bracket_ (T.handshake ctx)                                    (liftIO $ silentBye ctx)                                    (k conn)  -- | Like 'useTls', except it also fully closes the TCP connection when done. useTlsThenClose-  :: (MonadIO m, C.MonadMask m)+  :: (MonadIO m, E.MonadMask m)   => ((Context, SockAddr) -> m a)   -> ((Context, SockAddr) -> m a) useTlsThenClose k conn@(ctx,_) = do-    useTls k conn `C.finally` liftIO (T.contextClose ctx)+    useTls k conn `E.finally` liftIO (T.contextClose ctx)  -- | Similar to 'useTlsThenClose', except it performs the all the IO actions -- in a new  thread.