diff options
Diffstat (limited to 'acme.hs')
-rw-r--r-- | acme.hs | 23 |
1 files changed, 16 insertions, 7 deletions
@@ -44,6 +44,7 @@ import Options.Applicative hiding (header) | |||
44 | import qualified Options.Applicative as Opt | 44 | import qualified Options.Applicative as Opt |
45 | import Pipes | 45 | import Pipes |
46 | import System.Directory | 46 | import System.Directory |
47 | import Text.Email.Validate | ||
47 | 48 | ||
48 | stagingDirectoryUrl, liveDirectoryUrl :: String | 49 | stagingDirectoryUrl, liveDirectoryUrl :: String |
49 | liveDirectoryUrl = "https://acme-v01.api.letsencrypt.org/directory" | 50 | liveDirectoryUrl = "https://acme-v01.api.letsencrypt.org/directory" |
@@ -154,15 +155,21 @@ go CmdOpts { .. } = do | |||
154 | 155 | ||
155 | Just keys <- readKeyFile privKeyFile | 156 | Just keys <- readKeyFile privKeyFile |
156 | 157 | ||
157 | doesFileExist domainCSRFile `otherwiseM` genReq domainKeyFile requestDomains >>= LC.writeFile domainCSRFile | ||
158 | |||
159 | csrData <- B.readFile domainCSRFile | ||
160 | |||
161 | ensureWritable optChallengeDir "challenge directory" | 158 | ensureWritable optChallengeDir "challenge directory" |
162 | ensureWritable domainDir "domain directory" | 159 | ensureWritable domainDir "domain directory" |
163 | 160 | ||
164 | forM_ requestDomains $ canProvision optChallengeDir >=> (`unless` error "Error: cannot provision files to web server via challenge directory") | 161 | forM_ requestDomains $ canProvision optChallengeDir >=> (`unless` error "Error: cannot provision files to web server via challenge directory") |
165 | 162 | ||
163 | csrData <- CSR . toStrict <$> genReq domainKeyFile requestDomains | ||
164 | B.writeFile domainCSRFile (coerce csrData) | ||
165 | |||
166 | let email = either (error . ("Error: invalid email address: " ++)) id . validate . fromString <$> optEmail | ||
167 | |||
168 | certify directoryUrl keys email terms requestDomains optChallengeDir csrData domainCertFile | ||
169 | |||
170 | certify :: String -> Keys -> Maybe EmailAddress -> String -> [String] -> String -> CSR -> FilePath -> IO () | ||
171 | certify directoryUrl keys optEmail terms requestDomains optChallengeDir csrData domainCertFile = | ||
172 | |||
166 | runACME directoryUrl keys $ do | 173 | runACME directoryUrl keys $ do |
167 | forM_ optEmail $ register terms >=> statusReport | 174 | forM_ optEmail $ register terms >=> statusReport |
168 | 175 | ||
@@ -178,6 +185,8 @@ go CmdOpts { .. } = do | |||
178 | 185 | ||
179 | retrieveCert csrData >>= statusReport >>= saveCert domainCertFile | 186 | retrieveCert csrData >>= statusReport >>= saveCert domainCertFile |
180 | 187 | ||
188 | newtype CSR = CSR ByteString | ||
189 | |||
181 | (</>) :: String -> String -> String | 190 | (</>) :: String -> String -> String |
182 | a </> b = a ++ "/" ++ b | 191 | a </> b = a ++ "/" ++ b |
183 | infixr 5 </> | 192 | infixr 5 </> |
@@ -234,8 +243,8 @@ saveCert domainCertFile r = | |||
234 | where | 243 | where |
235 | isSuccess n = n >= 200 && n <= 300 | 244 | isSuccess n = n >= 200 && n <= 300 |
236 | 245 | ||
237 | retrieveCert :: (MonadReader Env m, MonadState Nonce m, MonadIO m) => ByteString -> m (Response LC.ByteString) | 246 | retrieveCert :: (MonadReader Env m, MonadState Nonce m, MonadIO m) => CSR -> m (Response LC.ByteString) |
238 | retrieveCert input = sendPayload _newCert (csr input) | 247 | retrieveCert input = sendPayload _newCert (csr $ coerce input) |
239 | 248 | ||
240 | notifyChallenge :: (MonadReader Env m, MonadState Nonce m, MonadIO m) => String -> ByteString -> m (Response LC.ByteString) | 249 | notifyChallenge :: (MonadReader Env m, MonadState Nonce m, MonadIO m) => String -> ByteString -> m (Response LC.ByteString) |
241 | notifyChallenge crUri thumbtoken = sendPayload (const crUri) (challenge thumbtoken) | 250 | notifyChallenge crUri thumbtoken = sendPayload (const crUri) (challenge thumbtoken) |
@@ -263,7 +272,7 @@ getDirectory sess url = do | |||
263 | k x = r ^? responseBody . JSON.key x . _String . to T.unpack | 272 | k x = r ^? responseBody . JSON.key x . _String . to T.unpack |
264 | return $ (,) <$> (Directory <$> k "new-cert" <*> k "new-authz" <*> k "revoke-cert" <*> k "new-reg") <*> nonce | 273 | return $ (,) <$> (Directory <$> k "new-cert" <*> k "new-authz" <*> k "revoke-cert" <*> k "new-reg") <*> nonce |
265 | 274 | ||
266 | register :: String -> String -> ACME (Response LC.ByteString) | 275 | register :: String -> EmailAddress -> ACME (Response LC.ByteString) |
267 | register terms email = sendPayload _newReg (registration email terms) | 276 | register terms email = sendPayload _newReg (registration email terms) |
268 | 277 | ||
269 | challengeRequest :: (MonadIO m, MonadState Nonce m, MonadReader Env m) => String -> m (Response LC.ByteString) | 278 | challengeRequest :: (MonadIO m, MonadState Nonce m, MonadReader Env m) => String -> m (Response LC.ByteString) |