1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
module Propellor.Types.PrivData where
import Propellor.Types.OS
import Utility.PartialPrelude
import Utility.FileSystemEncoding
import Data.Maybe
import qualified Data.ByteString.Lazy as L
-- | Note that removing or changing constructors or changing types will
-- break the serialized privdata files, so don't do that!
-- It's fine to add new constructors.
data PrivDataField
= DockerAuthentication
| SshPubKey SshKeyType UserName -- ^ Not used anymore, but retained to avoid breaking serialization of old files
| SshPrivKey SshKeyType UserName -- ^ For host key, use empty UserName
| SshAuthorizedKeys UserName
| Password UserName
| CryptPassword UserName
| PrivFile FilePath
| GpgKey
| DnsSec DnsSecKey
deriving (Read, Show, Ord, Eq)
-- | Combines a PrivDataField with a description of how to generate
-- its value.
data PrivDataSource
= PrivDataSourceFile PrivDataField FilePath
| PrivDataSourceFileFromCommand PrivDataField FilePath String
| PrivDataSource PrivDataField String
type PrivDataSourceDesc = String
class IsPrivDataSource s where
privDataField :: s -> PrivDataField
describePrivDataSource :: s -> Maybe PrivDataSourceDesc
instance IsPrivDataSource PrivDataField where
privDataField = id
describePrivDataSource _ = Nothing
instance IsPrivDataSource PrivDataSource where
privDataField s = case s of
PrivDataSourceFile f _ -> f
PrivDataSourceFileFromCommand f _ _ -> f
PrivDataSource f _ -> f
describePrivDataSource s = Just $ case s of
PrivDataSourceFile _ f -> "< " ++ f
PrivDataSourceFileFromCommand _ f c ->
"< " ++ f ++ " (created by running, for example, `" ++ c ++ "` )"
PrivDataSource _ d -> "< (" ++ d ++ ")"
-- | A context in which a PrivDataField is used.
--
-- Often this will be a domain name. For example,
-- Context "www.example.com" could be used for the SSL cert
-- for the web server serving that domain. Multiple hosts might
-- use that privdata.
--
-- This appears in serialized privdata files.
newtype Context = Context String
deriving (Read, Show, Ord, Eq)
-- | A context that may vary depending on the HostName where it's used.
newtype HostContext = HostContext { mkHostContext :: HostName -> Context }
instance Show HostContext where
show hc = show $ mkHostContext hc "<hostname>"
instance Ord HostContext where
a <= b = show a <= show b
instance Eq HostContext where
a == b = show a == show b
-- | Class of things that can be used as a Context.
class IsContext c where
asContext :: HostName -> c -> Context
asHostContext :: c -> HostContext
instance IsContext HostContext where
asContext = flip mkHostContext
asHostContext = id
instance IsContext Context where
asContext _ c = c
asHostContext = HostContext . const
-- | Use when a PrivDataField is not dependent on any paricular context.
anyContext :: Context
anyContext = Context "any"
-- | Makes a HostContext that consists just of the hostname.
hostContext :: HostContext
hostContext = HostContext Context
-- | Contains the actual private data.
--
-- Note that this may contain exta newlines at the end, or they may have
-- been stripped off, depending on how the user entered the privdata,
-- and which version of propellor stored it. Use the accessor functions
-- below to avoid newline problems.
newtype PrivData = PrivData String
-- | When PrivData is the content of a file, this is the lines thereof.
privDataLines :: PrivData -> [String]
privDataLines (PrivData s) = lines s
-- | When the PrivData is a single value, like a password, this extracts
-- it. Note that if multiple lines are present in the PrivData, only
-- the first is returned; there is never a newline in the String.
privDataVal :: PrivData -> String
privDataVal (PrivData s) = fromMaybe "" (headMaybe (lines s))
-- | Use to get ByteString out of PrivData.
privDataByteString :: PrivData -> L.ByteString
privDataByteString (PrivData s) = encodeBS s
data SshKeyType = SshRsa | SshDsa | SshEcdsa | SshEd25519
deriving (Read, Show, Ord, Eq, Enum, Bounded)
-- | Parameter that would be passed to ssh-keygen to generate key of this type
sshKeyTypeParam :: SshKeyType -> String
sshKeyTypeParam SshRsa = "RSA"
sshKeyTypeParam SshDsa = "DSA"
sshKeyTypeParam SshEcdsa = "ECDSA"
sshKeyTypeParam SshEd25519 = "ED25519"
data DnsSecKey
= PubZSK -- ^ DNSSEC Zone Signing Key (public)
| PrivZSK -- ^ DNSSEC Zone Signing Key (private)
| PubKSK -- ^ DNSSEC Key Signing Key (public)
| PrivKSK -- ^ DNSSEC Key Signing Key (private)
deriving (Read, Show, Ord, Eq, Bounded, Enum)
|