summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2016-01-26 03:17:47 -0500
committerAndrew Cady <d@jerkface.net>2016-01-26 14:11:41 -0500
commit7373a3ede2216048d2766f8f27e77d014b82dc43 (patch)
tree73ce059e25e0131e7d6f8363338a9a19f8532ef4
parentd54ff778995b369ead6b708d9b6ee8bff31d366d (diff)
use Control.Error
-rw-r--r--acme-certify.cabal2
-rw-r--r--src/Network/ACME.hs33
2 files changed, 19 insertions, 16 deletions
diff --git a/acme-certify.cabal b/acme-certify.cabal
index 60bf41a..b9e9818 100644
--- a/acme-certify.cabal
+++ b/acme-certify.cabal
@@ -17,7 +17,7 @@ library
17 build-depends: base >= 4.7 && < 5, 17 build-depends: base >= 4.7 && < 5,
18 cryptonite, aeson, bytestring, base64-bytestring, SHA, 18 cryptonite, aeson, bytestring, base64-bytestring, SHA,
19 mtl, text, HsOpenSSL, wreq, lens, lens-aeson, time, 19 mtl, text, HsOpenSSL, wreq, lens, lens-aeson, time,
20 email-validate, pipes, directory, network-uri 20 email-validate, pipes, directory, network-uri, errors
21 default-language: Haskell2010 21 default-language: Haskell2010
22 22
23executable acme-certify 23executable acme-certify
diff --git a/src/Network/ACME.hs b/src/Network/ACME.hs
index b05b823..e08d5b9 100644
--- a/src/Network/ACME.hs
+++ b/src/Network/ACME.hs
@@ -41,6 +41,8 @@ import OpenSSL.RSA
41import OpenSSL.X509.Request 41import OpenSSL.X509.Request
42import OpenSSL.X509 (readDerX509, X509) 42import OpenSSL.X509 (readDerX509, X509)
43import Data.List 43import Data.List
44import Control.Error
45import Control.Arrow
44 46
45type HttpProvisioner = URI -> ByteString -> IO () 47type HttpProvisioner = URI -> ByteString -> IO ()
46 48
@@ -73,23 +75,24 @@ acmeChallengeURI dom tok = URI
73 "" 75 ""
74 76
75certify :: URI -> Keys -> Maybe (URI, EmailAddress) -> HttpProvisioner -> CSR -> IO (Either String X509) 77certify :: URI -> Keys -> Maybe (URI, EmailAddress) -> HttpProvisioner -> CSR -> IO (Either String X509)
76certify directoryUrl keys reg provision certReq = run >>= traverse readDerX509 78certify directoryUrl keys reg provision certReq =
77 79
78 where 80 (mapM readDerX509 =<<) $ runACME directoryUrl keys $ do
79 run = 81
80 runACME directoryUrl keys $ do 82 forM_ reg $ uncurry register >=> statusReport
81 forM_ reg $ uncurry register >=> statusReport
82 83
83 let performChallenge domain (ChallengeRequest nextUri token thumbtoken) = do 84 let performChallenge domain (ChallengeRequest nextUri token thumbtoken) = do
84 liftIO $ provision (acmeChallengeURI domain token) thumbtoken 85 liftIO $ provision (acmeChallengeURI domain token) thumbtoken
85 notifyChallenge nextUri thumbtoken >>= statusReport >>= ncErrorReport 86 notifyChallenge nextUri thumbtoken >>= statusReport >>= ncErrorReport
86 87
87 challengeResultLinks <- forM (csrDomains certReq) $ \dom -> 88 challengeResultLinks <- forM (csrDomains certReq) $ \dom -> challengeRequest dom >>=
88 challengeRequest dom >>= statusReport >>= extractCR >>= performChallenge dom 89 statusReport >>=
90 extractCR >>=
91 performChallenge dom
89 92
90 pollResults challengeResultLinks >>= 93 runExceptT $ do
91 either (return . Left . ("certificate receipt was not attempted because a challenge failed: " ++)) 94 ExceptT $ pollResults challengeResultLinks <&> left ("certificate receipt was not attempted because a challenge failed: " ++)
92 (const (retrieveCert certReq >>= statusReport <&> checkCertResponse)) 95 ExceptT $ retrieveCert certReq >>= statusReport <&> checkCertResponse
93 96
94pollResults :: [Response LC.ByteString] -> ACME (Either String ()) 97pollResults :: [Response LC.ByteString] -> ACME (Either String ())
95pollResults [] = return $ Right () 98pollResults [] = return $ Right ()
@@ -111,9 +114,9 @@ data CSR = CSR { csrDomains :: [DomainName], csrData :: ByteString }
111newtype WritableDir = WritableDir String 114newtype WritableDir = WritableDir String
112ensureWritableDir :: FilePath -> String -> IO WritableDir 115ensureWritableDir :: FilePath -> String -> IO WritableDir
113ensureWritableDir file name = do 116ensureWritableDir file name = do
114 (writable <$> getPermissions file) >>= flip unless (err name) 117 (writable <$> getPermissions file) >>= flip unless (e name)
115 return $ WritableDir file 118 return $ WritableDir file
116 where err n = error $ "Error: " ++ n ++ " is not writable" 119 where e n = error $ "Error: " ++ n ++ " is not writable"
117 120
118(</>) :: String -> String -> String 121(</>) :: String -> String -> String
119a </> b = a ++ "/" ++ b 122a </> b = a ++ "/" ++ b