diff options
| author | Joey Hess <joeyh@joeyh.name> | 2015-12-19 16:42:45 -0400 |
|---|---|---|
| committer | Joey Hess <joeyh@joeyh.name> | 2015-12-19 16:42:45 -0400 |
| commit | 35113853cd1118a12debbdac2df85c02076f5a8f (patch) | |
| tree | 810fa01bd47c5f31f6972cd1d1bf7c93b1d61cf7 /src/Propellor | |
| parent | 4d12d728dd1ef087af39de142c0c5422495305b9 (diff) | |
| parent | 4e4c7bb914779ded627bc28de116acd8b0867986 (diff) | |
Merge branch 'joeyconfig'
Diffstat (limited to 'src/Propellor')
| -rw-r--r-- | src/Propellor/Gpg.hs | 10 | ||||
| -rw-r--r-- | src/Propellor/Property/Gpg.hs | 39 |
2 files changed, 34 insertions, 15 deletions
diff --git a/src/Propellor/Gpg.hs b/src/Propellor/Gpg.hs index 960c70d3..949eb5b5 100644 --- a/src/Propellor/Gpg.hs +++ b/src/Propellor/Gpg.hs @@ -79,12 +79,12 @@ rmKey keyid = exitBool =<< allM (uncurry actionMessage) ] where rmkeyring = boolSystem "gpg" $ - (map Param useKeyringOpts) ++ + (map Param useKeyringOpts) ++ [ Param "--batch" , Param "--yes" , Param "--delete-key", Param keyid ] - + gitconfig = ifM ((==) (keyid++"\n", True) <$> processTranscript "git" ["config", "user.signingkey"] Nothing) ( boolSystem "git" [ Param "config" @@ -92,7 +92,7 @@ rmKey keyid = exitBool =<< allM (uncurry actionMessage) , Param "user.signingkey" ] , return True - ) + ) reencryptPrivData :: IO Bool reencryptPrivData = ifM (doesFileExist privDataFile) @@ -101,7 +101,7 @@ reencryptPrivData = ifM (doesFileExist privDataFile) gitAdd privDataFile , return True ) - + gitAdd :: FilePath -> IO Bool gitAdd f = boolSystem "git" [ Param "add" @@ -125,7 +125,7 @@ gpgSignParams ps = ifM (doesFileExist keyring) -- Automatically sign the commit if there'a a keyring. gitCommit :: Maybe String -> [CommandParam] -> IO Bool gitCommit msg ps = do - let ps' = Param "commit" : ps ++ + let ps' = Param "commit" : ps ++ maybe [] (\m -> [Param "-m", Param m]) msg ps'' <- gpgSignParams ps' if isNothing msg diff --git a/src/Propellor/Property/Gpg.hs b/src/Propellor/Property/Gpg.hs index a16df11d..bd710ca7 100644 --- a/src/Propellor/Property/Gpg.hs +++ b/src/Propellor/Property/Gpg.hs @@ -12,6 +12,8 @@ installed = Apt.installed ["gnupg"] -- A numeric id, or a description of the key, in a form understood by gpg. newtype GpgKeyId = GpgKeyId { getGpgKeyId :: String } +data GpgKeyType = GpgPubKey | GpgPrivKey + -- | Sets up a user with a gpg key from the privdata. -- -- Note that if a secret key is exported using gpg -a --export-secret-key, @@ -21,22 +23,39 @@ newtype GpgKeyId = GpgKeyId { getGpgKeyId :: String } -- Recommend only using this for low-value dedicated role keys. -- No attempt has been made to scrub the key out of memory once it's used. keyImported :: GpgKeyId -> User -> Property HasInfo -keyImported (GpgKeyId keyid) user@(User u) = flagFile' prop genflag +keyImported key@(GpgKeyId keyid) user@(User u) = prop `requires` installed where desc = u ++ " has gpg key " ++ show keyid - genflag = do - d <- dotDir user - return $ d </> ".propellor-imported-keyid-" ++ keyid prop = withPrivData src (Context keyid) $ \getkey -> - property desc $ getkey $ \key -> makeChange $ - withHandle StdinHandle createProcessSuccess - (proc "su" ["-c", "gpg --import", u]) $ \h -> do - fileEncoding h - hPutStr h (unlines (privDataLines key)) - hClose h + property desc $ getkey $ \key' -> do + let keylines = privDataLines key' + ifM (liftIO $ hasGpgKey (parse keylines)) + ( return NoChange + , makeChange $ withHandle StdinHandle createProcessSuccess + (proc "su" ["-c", "gpg --import", u]) $ \h -> do + fileEncoding h + hPutStr h (unlines keylines) + hClose h + ) src = PrivDataSource GpgKey "Either a gpg public key, exported with gpg --export -a, or a gpg private key, exported with gpg --export-secret-key -a" + parse ("-----BEGIN PGP PUBLIC KEY BLOCK-----":_) = Just GpgPubKey + parse ("-----BEGIN PGP PRIVATE KEY BLOCK-----":_) = Just GpgPrivKey + parse _ = Nothing + + hasGpgKey Nothing = error $ "Failed to run gpg parser on armored key " ++ keyid + hasGpgKey (Just GpgPubKey) = hasPubKey key user + hasGpgKey (Just GpgPrivKey) = hasPrivKey key user + +hasPrivKey :: GpgKeyId -> User -> IO Bool +hasPrivKey (GpgKeyId keyid) (User u) = catchBoolIO $ + snd <$> processTranscript "su" ["-c", "gpg --list-secret-keys " ++ shellEscape keyid, u] Nothing + +hasPubKey :: GpgKeyId -> User -> IO Bool +hasPubKey (GpgKeyId keyid) (User u) = catchBoolIO $ + snd <$> processTranscript "su" ["-c", "gpg --list-public-keys " ++ shellEscape keyid, u] Nothing + dotDir :: User -> IO FilePath dotDir (User u) = do home <- homeDirectory <$> getUserEntryForName u |
