summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoey Hess2015-12-19 16:42:45 -0400
committerJoey Hess2015-12-19 16:42:45 -0400
commit35113853cd1118a12debbdac2df85c02076f5a8f (patch)
tree810fa01bd47c5f31f6972cd1d1bf7c93b1d61cf7 /src
parent4d12d728dd1ef087af39de142c0c5422495305b9 (diff)
parent4e4c7bb914779ded627bc28de116acd8b0867986 (diff)
Merge branch 'joeyconfig'
Diffstat (limited to 'src')
-rw-r--r--src/Propellor/Gpg.hs10
-rw-r--r--src/Propellor/Property/Gpg.hs39
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