summaryrefslogtreecommitdiff
path: root/src/Propellor/PrivData.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Propellor/PrivData.hs')
-rw-r--r--src/Propellor/PrivData.hs20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/Propellor/PrivData.hs b/src/Propellor/PrivData.hs
index 9b62720f..cb099c87 100644
--- a/src/Propellor/PrivData.hs
+++ b/src/Propellor/PrivData.hs
@@ -23,6 +23,7 @@ module Propellor.PrivData (
PrivMap,
PrivInfo,
forceHostContext,
+ passwordGen,
) where
import System.IO
@@ -59,6 +60,7 @@ import Utility.FileMode
import Utility.Env
import Utility.Table
import Utility.Directory
+import Utility.Process
-- | Allows a Property to access the value of a specific PrivDataField,
-- for use in a specific Context or HostContext.
@@ -293,3 +295,21 @@ forceHostContext :: String -> PrivInfo -> PrivInfo
forceHostContext name i = PrivInfo $ S.map go (fromPrivInfo i)
where
go (f, d, HostContext ctx) = (f, d, HostContext (const $ ctx name))
+
+-- | Generate a password by hashing some salt with the context and a seed.
+--
+-- Salt is stored in a privdata, seed comes from the user, the service or any
+-- fixed string to identify the usage. They are combined together and
+-- securely hashed to generate the password. This can be used to generate
+-- many specialized password from a single secret.
+--
+-- This also means that if the secret privdata is leaked, all the generated
+-- passwords are leaked too!
+passwordGen :: PrivData -> Context -> String -> IO String
+passwordGen (PrivData salt) (Context context) seed =
+ parseSum <$> writeReadProcessEnv "sha256sum" [] Nothing
+ (Just writer) Nothing
+ where
+ writer h = hPutStr h combined
+ combined = salt ++ ":" ++ context ++ ":" ++ seed
+ parseSum = Data.List.head . words