diff options
author | Andrew Cady <d@jerkface.net> | 2016-04-09 23:07:34 -0400 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2016-04-09 23:08:23 -0400 |
commit | 2aceca9e7c7e0d39efc66a65168ceb3d9c587be5 (patch) | |
tree | 0eae378dba49919cab38d2ecddf948379d99ff27 | |
parent | 2767871a0dc502b369a9baa0a6f55dc541cc1e13 (diff) |
successfully retrieved certificate with update code
-rw-r--r-- | acme-certify.hs | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/acme-certify.hs b/acme-certify.hs index 5f4c24d..15b729f 100644 --- a/acme-certify.hs +++ b/acme-certify.hs | |||
@@ -21,8 +21,8 @@ import Control.Monad.IO.Class | |||
21 | import Control.Monad.Trans.Resource | 21 | import Control.Monad.Trans.Resource |
22 | import Data.Aeson.Lens | 22 | import Data.Aeson.Lens |
23 | import qualified Data.HashMap.Strict as HashMap | 23 | import qualified Data.HashMap.Strict as HashMap |
24 | import Data.Text (Text, unpack) | 24 | import Data.Text (Text, unpack, pack) |
25 | import Data.Text.Encoding (decodeUtf8) | 25 | import Data.Text.Encoding (decodeUtf8, encodeUtf8) |
26 | import Data.Yaml (Object) | 26 | import Data.Yaml (Object) |
27 | import qualified Data.Yaml.Config as Config | 27 | import qualified Data.Yaml.Config as Config |
28 | import Data.Yaml.Config.Internal (Config (..)) | 28 | import Data.Yaml.Config.Internal (Config (..)) |
@@ -187,13 +187,23 @@ runUpdate UpdateOpts { .. } = do | |||
187 | threadDelay $ 1000 * 1000 * 10 | 187 | threadDelay $ 1000 * 1000 * 10 |
188 | removeTemp h | 188 | removeTemp h |
189 | 189 | ||
190 | issuerCert <- readX509 letsEncryptX1CrossSigned | ||
191 | |||
190 | forM_ certReqDomains $ \(host, domains) -> do | 192 | forM_ certReqDomains $ \(host, domains) -> do |
191 | when (host == "fifty") $ do | 193 | when (host == "fifty") $ do |
192 | putStrLn host | 194 | putStrLn host |
193 | let cs = dereference (map (chooseProvisioner host) domains) <&> certSpec globalCertificateDir keys host | 195 | let Just spec = dereference (map (chooseProvisioner host) domains) <&> certSpec globalCertificateDir keys host |
194 | print cs | 196 | print spec |
195 | error "Error: unimplemented" | 197 | |
196 | 198 | when True $ | |
199 | forM_ (csDomains spec) $ uncurry canProvision >=> | ||
200 | (`unless` error "Error: cannot provision files to web server") | ||
201 | let terms = defaultTerms | ||
202 | directoryUrl = stagingDirectoryUrl | ||
203 | email = emailAddress $ encodeUtf8 . pack $ "root@" ++ (domainToString . fst . head) (csDomains spec) | ||
204 | print =<< fetchCertificate directoryUrl terms email issuerCert spec | ||
205 | |||
206 | error "Error: unimplemented" | ||
197 | where | 207 | where |
198 | 208 | ||
199 | dereference :: [(DomainName, Either DomainName HttpProvisioner)] -> Maybe [(DomainName, HttpProvisioner)] | 209 | dereference :: [(DomainName, Either DomainName HttpProvisioner)] -> Maybe [(DomainName, HttpProvisioner)] |
@@ -245,14 +255,19 @@ data TempRemover = TempRemover { removeTemp :: IO () } | |||
245 | remoteTemp :: String -> FilePath -> String -> IO TempRemover | 255 | remoteTemp :: String -> FilePath -> String -> IO TempRemover |
246 | remoteTemp host fileName content = do | 256 | remoteTemp host fileName content = do |
247 | (inp,out,err,_pid) <- ssh $ unlines | 257 | (inp,out,err,_pid) <- ssh $ unlines |
248 | [ "printf '%s' " ++ escape content ++ " > " ++ escape fileName | 258 | [ "mkdir -p " ++ escape (dirname fileName) |
259 | , "printf '%s' " ++ escape content ++ " > " ++ escape fileName | ||
260 | , "echo provisioned." | ||
249 | , "trap " ++ (escape . unwords) ["rm -f", escape fileName] ++ " EXIT" | 261 | , "trap " ++ (escape . unwords) ["rm -f", escape fileName] ++ " EXIT" |
250 | , "read line" | 262 | , "read line" |
251 | ] | 263 | ] |
264 | void $ hGetLine out | ||
252 | return $ TempRemover $ mapM_ hClose [inp, out, err] | 265 | return $ TempRemover $ mapM_ hClose [inp, out, err] |
253 | where | 266 | where |
254 | ssh cmd = runInteractiveProcess "ssh" (host : words "-- sh -c" ++ [escape cmd]) Nothing Nothing | 267 | ssh cmd = runInteractiveProcess "ssh" (host : words "-- sh -c" ++ [escape cmd]) Nothing Nothing |
255 | 268 | ||
269 | dirname = dropWhileEnd (/= '/') | ||
270 | |||
256 | provisionViaRemoteFile :: String -> FilePath -> HttpProvisioner | 271 | provisionViaRemoteFile :: String -> FilePath -> HttpProvisioner |
257 | provisionViaRemoteFile = provision | 272 | provisionViaRemoteFile = provision |
258 | where | 273 | where |
@@ -279,7 +294,7 @@ runCertify CertifyOpts{..} = do | |||
279 | 294 | ||
280 | Just keys <- getOrCreateKeys privKeyFile | 295 | Just keys <- getOrCreateKeys privKeyFile |
281 | 296 | ||
282 | let req = CertSpec {..} | 297 | let spec = CertSpec {..} |
283 | csDomains = map (flip (,) (provisionViaFile challengeDir)) requestDomains | 298 | csDomains = map (flip (,) (provisionViaFile challengeDir)) requestDomains |
284 | csSkipDH = optSkipDH | 299 | csSkipDH = optSkipDH |
285 | csUserKeys = keys | 300 | csUserKeys = keys |
@@ -289,7 +304,7 @@ runCertify CertifyOpts{..} = do | |||
289 | forM_ csDomains $ uncurry canProvision >=> | 304 | forM_ csDomains $ uncurry canProvision >=> |
290 | (`unless` error "Error: cannot provision files to web server") | 305 | (`unless` error "Error: cannot provision files to web server") |
291 | 306 | ||
292 | fetchCertificate directoryUrl terms email issuerCert req | 307 | fetchCertificate directoryUrl terms email issuerCert spec |
293 | 308 | ||
294 | fetchCertificate :: URI -> URI -> Maybe EmailAddress -> X509 -> CertSpec -> IO (Either String ()) | 309 | fetchCertificate :: URI -> URI -> Maybe EmailAddress -> X509 -> CertSpec -> IO (Either String ()) |
295 | fetchCertificate directoryUrl terms email issuerCert cs@CertSpec{..} = do | 310 | fetchCertificate directoryUrl terms email issuerCert cs@CertSpec{..} = do |
@@ -321,6 +336,7 @@ genKey = withOpenSSL $ do | |||
321 | getOrCreate :: IO String -> (String -> IO a) -> FilePath -> IO a | 336 | getOrCreate :: IO String -> (String -> IO a) -> FilePath -> IO a |
322 | getOrCreate gen parse file = do | 337 | getOrCreate gen parse file = do |
323 | exists <- doesFileExist file | 338 | exists <- doesFileExist file |
339 | createDirectoryIfMissing True (dirname file) | ||
324 | parse =<< if exists then readFile file else gen >>= save file | 340 | parse =<< if exists then readFile file else gen >>= save file |
325 | where | 341 | where |
326 | save f x = writeFile f x >> return x | 342 | save f x = writeFile f x >> return x |