diff options
author | Andrew Cady <d@jerkface.net> | 2016-04-09 19:42:31 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2016-04-09 19:42:31 -0400 |
commit | 70137d8dba49353f525b4d3e93a919df80e81765 (patch) | |
tree | 1b51f8f48d28298ff93a6605394a2676d7e24ee0 | |
parent | 5ccdc88c25f9a94e7b5db135a0876d606685a690 (diff) |
implement remote file http provisioner
-rw-r--r-- | acme-certify.cabal | 3 | ||||
-rw-r--r-- | acme-certify.hs | 42 |
2 files changed, 29 insertions, 16 deletions
diff --git a/acme-certify.cabal b/acme-certify.cabal index 5c89233..364e269 100644 --- a/acme-certify.cabal +++ b/acme-certify.cabal | |||
@@ -29,7 +29,8 @@ executable acme | |||
29 | cryptonite, aeson, bytestring, base64-bytestring, SHA, | 29 | cryptonite, aeson, bytestring, base64-bytestring, SHA, |
30 | text, HsOpenSSL, optparse-applicative, time, | 30 | text, HsOpenSSL, optparse-applicative, time, |
31 | email-validate, network-uri, directory, yaml-config, | 31 | email-validate, network-uri, directory, yaml-config, |
32 | yaml, unordered-containers, lens, lens-aeson, process, posix-escape | 32 | yaml, unordered-containers, lens, lens-aeson, process, |
33 | posix-escape, transformers, resourcet | ||
33 | default-language: Haskell2010 | 34 | default-language: Haskell2010 |
34 | 35 | ||
35 | -- test-suite acme-certify-test | 36 | -- test-suite acme-certify-test |
diff --git a/acme-certify.hs b/acme-certify.hs index 1e9655c..5f4613f 100644 --- a/acme-certify.hs +++ b/acme-certify.hs | |||
@@ -6,6 +6,7 @@ | |||
6 | {-# LANGUAGE RecordWildCards #-} | 6 | {-# LANGUAGE RecordWildCards #-} |
7 | {-# LANGUAGE ScopedTypeVariables #-} | 7 | {-# LANGUAGE ScopedTypeVariables #-} |
8 | {-# LANGUAGE TypeSynonymInstances #-} | 8 | {-# LANGUAGE TypeSynonymInstances #-} |
9 | {-# LANGUAGE ViewPatterns #-} | ||
9 | 10 | ||
10 | -------------------------------------------------------------------------------- | 11 | -------------------------------------------------------------------------------- |
11 | -- | Get a certificate from Let's Encrypt using the ACME protocol. | 12 | -- | Get a certificate from Let's Encrypt using the ACME protocol. |
@@ -15,31 +16,35 @@ | |||
15 | module Main where | 16 | module Main where |
16 | 17 | ||
17 | import BasePrelude | 18 | import BasePrelude |
18 | import Control.Lens hiding ((&)) | 19 | import Control.Lens hiding ((&)) |
20 | import Control.Monad.IO.Class | ||
21 | import Control.Monad.Trans.Resource | ||
19 | import Data.Aeson.Lens | 22 | import Data.Aeson.Lens |
20 | import qualified Data.HashMap.Strict as HashMap | 23 | import qualified Data.HashMap.Strict as HashMap |
21 | import Data.Text (Text, unpack) | 24 | import Data.Text (Text, unpack) |
22 | import Data.Yaml (Object) | 25 | import Data.Text.Encoding (decodeUtf8) |
23 | import qualified Data.Yaml.Config as Config | 26 | import Data.Yaml (Object) |
24 | import Data.Yaml.Config.Internal (Config (..)) | 27 | import qualified Data.Yaml.Config as Config |
25 | import Network.ACME (HttpProvisioner, Keys (..), | 28 | import Data.Yaml.Config.Internal (Config (..)) |
26 | canProvision, certify, | 29 | import Network.ACME (HttpProvisioner, Keys (..), |
27 | ensureWritableDir, provisionViaFile, | 30 | canProvision, certify, |
28 | readKeys, (</>)) | 31 | ensureWritableDir, |
29 | import Network.ACME.Issuer (letsEncryptX1CrossSigned) | 32 | provisionViaFile, readKeys, |
33 | (</>)) | ||
34 | import Network.ACME.Issuer (letsEncryptX1CrossSigned) | ||
30 | import Network.URI | 35 | import Network.URI |
31 | import OpenSSL | 36 | import OpenSSL |
32 | import OpenSSL.DH | 37 | import OpenSSL.DH |
33 | import OpenSSL.PEM | 38 | import OpenSSL.PEM |
34 | import OpenSSL.RSA | 39 | import OpenSSL.RSA |
35 | import OpenSSL.X509 (X509) | 40 | import OpenSSL.X509 (X509) |
36 | import Options.Applicative hiding (header) | 41 | import Options.Applicative hiding (header) |
37 | import qualified Options.Applicative as Opt | 42 | import qualified Options.Applicative as Opt |
38 | import System.Directory | 43 | import System.Directory |
39 | import System.IO | 44 | import System.IO |
40 | import System.Posix.Escape | 45 | import System.Posix.Escape |
41 | import System.Process | 46 | import System.Process |
42 | import Text.Domain.Validate hiding (validate) | 47 | import Text.Domain.Validate hiding (validate) |
43 | import Text.Email.Validate | 48 | import Text.Email.Validate |
44 | 49 | ||
45 | stagingDirectoryUrl, liveDirectoryUrl, defaultTerms :: URI | 50 | stagingDirectoryUrl, liveDirectoryUrl, defaultTerms :: URI |
@@ -217,6 +222,13 @@ remoteTemp host fileName content = do | |||
217 | where | 222 | where |
218 | ssh cmd = runInteractiveProcess "ssh" (host : words "-- sh -c" ++ [escape cmd]) Nothing Nothing | 223 | ssh cmd = runInteractiveProcess "ssh" (host : words "-- sh -c" ++ [escape cmd]) Nothing Nothing |
219 | 224 | ||
225 | provisionViaRemoteFile :: String -> FilePath -> HttpProvisioner | ||
226 | provisionViaRemoteFile = provision | ||
227 | where | ||
228 | provision host dir (bsToS -> tok) (bsToS -> thumbtoken) = | ||
229 | void $ allocate (liftIO $ remoteTemp host (dir </> tok) thumbtoken) removeTemp | ||
230 | bsToS = unpack . decodeUtf8 | ||
231 | |||
220 | runCertify :: CertifyOpts -> IO (Either String ()) | 232 | runCertify :: CertifyOpts -> IO (Either String ()) |
221 | runCertify CertifyOpts{..} = do | 233 | runCertify CertifyOpts{..} = do |
222 | let terms = fromMaybe defaultTerms (join $ parseAbsoluteURI <$> optTerms) | 234 | let terms = fromMaybe defaultTerms (join $ parseAbsoluteURI <$> optTerms) |