Add simple TLS helpers: (#121)

- Check if ConnectInfo is secure

- Option to disable TLS certificate validation (to make testing
  easier).
This commit is contained in:
Aditya Manthramurthy 2019-05-13 11:42:34 -07:00 committed by Krishnan Parthasarathi
parent 663015fa9d
commit 76e5651d5a
4 changed files with 56 additions and 29 deletions

View File

@ -17,11 +17,11 @@
-- limitations under the License. -- limitations under the License.
-- --
{-# Language OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
import Network.Minio import Network.Minio
import Control.Monad.IO.Class (liftIO) import Control.Monad.IO.Class (liftIO)
import Prelude import Prelude
-- | The following example uses minio's play server at -- | The following example uses minio's play server at
-- https://play.min.io:9000. The endpoint and associated -- https://play.min.io:9000. The endpoint and associated
@ -39,5 +39,5 @@ main = do
liftIO $ putStrLn $ "Does " ++ show bucket ++ " exist? - " ++ show foundBucket liftIO $ putStrLn $ "Does " ++ show bucket ++ " exist? - " ++ show foundBucket
case res1 of case res1 of
Left e -> putStrLn $ "bucketExists failed." ++ show e Left e -> putStrLn $ "bucketExists failed." ++ show e
Right () -> return () Right () -> return ()

View File

@ -56,6 +56,7 @@ library
, case-insensitive >= 1.2 , case-insensitive >= 1.2
, conduit >= 1.3 , conduit >= 1.3
, conduit-extra >= 1.3 , conduit-extra >= 1.3
, connection
, containers >= 0.5 , containers >= 0.5
, cryptonite >= 0.25 , cryptonite >= 0.25
, cryptonite-conduit >= 0.2 , cryptonite-conduit >= 0.2
@ -64,6 +65,7 @@ library
, exceptions , exceptions
, filepath >= 1.4 , filepath >= 1.4
, http-client >= 0.5 , http-client >= 0.5
, http-client-tls
, http-conduit >= 2.3 , http-conduit >= 2.3
, http-types >= 0.12 , http-types >= 0.12
, ini , ini
@ -142,6 +144,7 @@ test-suite minio-hs-live-server-test
build-depends: base >= 4.7 && < 5 build-depends: base >= 4.7 && < 5
, minio-hs , minio-hs
, protolude >= 0.1.6 , protolude >= 0.1.6
, QuickCheck
, aeson , aeson
, base64-bytestring , base64-bytestring
, binary , binary
@ -149,6 +152,7 @@ test-suite minio-hs-live-server-test
, case-insensitive , case-insensitive
, conduit , conduit
, conduit-extra , conduit-extra
, connection
, containers , containers
, cryptonite , cryptonite
, cryptonite-conduit , cryptonite-conduit
@ -157,11 +161,11 @@ test-suite minio-hs-live-server-test
, exceptions , exceptions
, filepath , filepath
, http-client , http-client
, http-client-tls
, http-conduit , http-conduit
, http-types , http-types
, ini , ini
, memory , memory
, QuickCheck
, raw-strings-qq >= 1 , raw-strings-qq >= 1
, resourcet , resourcet
, retry , retry
@ -187,6 +191,7 @@ test-suite minio-hs-test
build-depends: base >= 4.7 && < 5 build-depends: base >= 4.7 && < 5
, minio-hs , minio-hs
, protolude >= 0.1.6 , protolude >= 0.1.6
, QuickCheck
, aeson , aeson
, base64-bytestring , base64-bytestring
, binary , binary
@ -194,19 +199,20 @@ test-suite minio-hs-test
, case-insensitive , case-insensitive
, conduit , conduit
, conduit-extra , conduit-extra
, connection
, containers , containers
, cryptonite , cryptonite
, cryptonite-conduit , cryptonite-conduit
, filepath
, digest , digest
, directory , directory
, exceptions , exceptions
, filepath
, http-client , http-client
, http-client-tls
, http-conduit , http-conduit
, http-types , http-types
, ini , ini
, memory , memory
, QuickCheck
, raw-strings-qq >= 1 , raw-strings-qq >= 1
, resourcet , resourcet
, retry , retry

View File

@ -39,6 +39,8 @@ module Network.Minio
, setRegion , setRegion
, setCreds , setCreds
, setCredsFrom , setCredsFrom
, isConnectInfoSecure
, disableTLSCertValidation
, MinioConn , MinioConn
, mkMinioConn , mkMinioConn

View File

@ -37,7 +37,9 @@ import qualified Data.Text as T
import qualified Data.Text.Encoding as TE import qualified Data.Text.Encoding as TE
import Data.Time (defaultTimeLocale, formatTime) import Data.Time (defaultTimeLocale, formatTime)
import GHC.Show (Show (show)) import GHC.Show (Show (show))
import qualified Network.Connection as Conn
import Network.HTTP.Client (defaultManagerSettings) import Network.HTTP.Client (defaultManagerSettings)
import qualified Network.HTTP.Client.TLS as TLS
import qualified Network.HTTP.Conduit as NC import qualified Network.HTTP.Conduit as NC
import Network.HTTP.Types (ByteRange, Header, Method, Query, import Network.HTTP.Types (ByteRange, Header, Method, Query,
hRange) hRange)
@ -94,28 +96,30 @@ awsRegionMap = Map.fromList [
-- `IsString` instance to provide a URL, for example: -- `IsString` instance to provide a URL, for example:
-- --
-- > let c :: ConnectInfo = "https://play.min.io:9000" -- > let c :: ConnectInfo = "https://play.min.io:9000"
data ConnectInfo = ConnectInfo { data ConnectInfo =
connectHost :: Text ConnectInfo { connectHost :: Text
, connectPort :: Int , connectPort :: Int
, connectAccessKey :: Text , connectAccessKey :: Text
, connectSecretKey :: Text , connectSecretKey :: Text
, connectIsSecure :: Bool , connectIsSecure :: Bool
, connectRegion :: Region , connectRegion :: Region
, connectAutoDiscoverRegion :: Bool , connectAutoDiscoverRegion :: Bool
} deriving (Eq, Show) , connectDisableTLSCertValidation :: Bool
} deriving (Eq, Show)
instance IsString ConnectInfo where instance IsString ConnectInfo where
fromString str = let req = NC.parseRequest_ str fromString str =
in ConnectInfo let req = NC.parseRequest_ str
{ connectHost = TE.decodeUtf8 $ NC.host req in ConnectInfo
, connectPort = NC.port req { connectHost = TE.decodeUtf8 $ NC.host req
, connectAccessKey = "" , connectPort = NC.port req
, connectSecretKey = "" , connectAccessKey = ""
, connectIsSecure = NC.secure req , connectSecretKey = ""
, connectRegion = "" , connectIsSecure = NC.secure req
, connectAutoDiscoverRegion = True , connectRegion = ""
} , connectAutoDiscoverRegion = True
, connectDisableTLSCertValidation = False
}
-- | Contains access key and secret key to access object storage. -- | Contains access key and secret key to access object storage.
data Credentials = Credentials { cAccessKey :: Text data Credentials = Credentials { cAccessKey :: Text
@ -187,6 +191,18 @@ setRegion r connInfo = connInfo { connectRegion = r
, connectAutoDiscoverRegion = False , connectAutoDiscoverRegion = False
} }
-- | Check if the connection to object storage server is secure
-- (i.e. uses TLS)
isConnectInfoSecure :: ConnectInfo -> Bool
isConnectInfoSecure = connectIsSecure
-- | Disable TLS certificate validation completely! This makes TLS
-- insecure! Use only for testing with self-signed or temporary
-- certificates. Note that this option has no effect, if you provide
-- your own Manager in `mkMinioConn`.
disableTLSCertValidation :: ConnectInfo -> ConnectInfo
disableTLSCertValidation c = c { connectDisableTLSCertValidation = True }
getHostAddr :: ConnectInfo -> ByteString getHostAddr :: ConnectInfo -> ByteString
getHostAddr ci = if | port == 80 || port == 443 -> toS host getHostAddr ci = if | port == 80 || port == 443 -> toS host
| otherwise -> toS $ | otherwise -> toS $
@ -955,7 +971,10 @@ instance HasSvcNamespace MinioConn where
-- object storage is accessed. -- object storage is accessed.
connect :: ConnectInfo -> IO MinioConn connect :: ConnectInfo -> IO MinioConn
connect ci = do connect ci = do
let settings | connectIsSecure ci = NC.tlsManagerSettings let settings | connectIsSecure ci && connectDisableTLSCertValidation ci =
let badTlsSettings = Conn.TLSSettingsSimple True False False
in TLS.mkManagerSettings badTlsSettings Nothing
| connectIsSecure ci = NC.tlsManagerSettings
| otherwise = defaultManagerSettings | otherwise = defaultManagerSettings
mgr <- NC.newManager settings mgr <- NC.newManager settings
mkMinioConn ci mgr mkMinioConn ci mgr