signstar_config/config/file/
impl_all.rs1use std::collections::HashSet;
11
12use signstar_common::backend::BackendType;
13use signstar_crypto::{
14 AdministrativeSecretHandling,
15 NonAdministrativeSecretHandling,
16 traits::UserWithPassphrase,
17};
18
19use crate::{
20 config::{
21 AuthorizedKeyEntry,
22 Config,
23 ConfigAuthorizedKeyEntries,
24 ConfigBuilder,
25 ConfigSystemUserData,
26 ConfigSystemUserIds,
27 MappingAuthorizedKeyEntry,
28 MappingBackendUserSecrets,
29 MappingSystemUserId,
30 SystemConfig,
31 SystemUserData,
32 SystemUserId,
33 UserBackendConnection,
34 UserBackendConnectionFilter,
35 traits::NonAdminBackendUserIdFilter,
36 },
37 nethsm::NetHsmUserMapping,
38 yubihsm2::YubiHsm2UserMapping,
39};
40
41impl UserBackendConnection {
42 pub fn admin_secret_handling(&self) -> AdministrativeSecretHandling {
44 match self {
45 Self::NetHsm {
46 admin_secret_handling,
47 ..
48 } => *admin_secret_handling,
49 Self::YubiHsm2 {
50 admin_secret_handling,
51 ..
52 } => *admin_secret_handling,
53 }
54 }
55
56 pub fn non_admin_secret_handling(&self) -> NonAdministrativeSecretHandling {
58 match self {
59 Self::NetHsm {
60 non_admin_secret_handling,
61 ..
62 } => *non_admin_secret_handling,
63 Self::YubiHsm2 {
64 non_admin_secret_handling,
65 ..
66 } => *non_admin_secret_handling,
67 }
68 }
69
70 pub fn create_non_admin_backend_user_secrets(
81 &self,
82 ) -> Result<Option<Vec<Box<dyn UserWithPassphrase>>>, crate::Error> {
83 match self {
84 Self::NetHsm {
85 non_admin_secret_handling,
86 mapping,
87 ..
88 } => mapping.create_non_admin_backend_user_secrets(*non_admin_secret_handling),
89 Self::YubiHsm2 {
90 non_admin_secret_handling,
91 mapping,
92 ..
93 } => mapping.create_non_admin_backend_user_secrets(*non_admin_secret_handling),
94 }
95 }
96
97 pub fn load_non_admin_backend_user_secrets(
108 &self,
109 filter: NonAdminBackendUserIdFilter,
110 ) -> Result<Option<Vec<Box<dyn UserWithPassphrase>>>, crate::Error> {
111 match self {
112 Self::NetHsm {
113 non_admin_secret_handling,
114 mapping,
115 ..
116 } => mapping.load_non_admin_backend_user_secrets(*non_admin_secret_handling, filter),
117 Self::YubiHsm2 {
118 non_admin_secret_handling,
119 mapping,
120 ..
121 } => mapping.load_non_admin_backend_user_secrets(*non_admin_secret_handling, filter),
122 }
123 }
124}
125
126impl MappingSystemUserId for UserBackendConnection {
127 fn system_user_id(&self) -> Option<&SystemUserId> {
128 match self {
129 Self::NetHsm { mapping, .. } => mapping.system_user_id(),
130 Self::YubiHsm2 { mapping, .. } => mapping.system_user_id(),
131 }
132 }
133}
134
135impl MappingAuthorizedKeyEntry for UserBackendConnection {
136 fn authorized_key_entry(&self) -> Option<&AuthorizedKeyEntry> {
137 match self {
138 Self::NetHsm { mapping, .. } => mapping.authorized_key_entry(),
139 Self::YubiHsm2 { mapping, .. } => mapping.authorized_key_entry(),
140 }
141 }
142}
143
144impl Config {
145 pub fn user_backend_connection(&self, user: &SystemUserId) -> Option<UserBackendConnection> {
147 if let Some(nethsm_config) = self.nethsm.as_ref()
148 && let Some(mapping) = nethsm_config
149 .mappings()
150 .iter()
151 .find(|mapping| mapping.system_user_id().is_some_and(|id| id == user))
152 {
153 return Some(UserBackendConnection::NetHsm {
154 admin_secret_handling: *self.system.admin_secret_handling(),
155 non_admin_secret_handling: *self.system.non_admin_secret_handling(),
156 connections: nethsm_config.connections().clone(),
157 mapping: mapping.clone(),
158 });
159 }
160
161 if let Some(yubihsm2_config) = self.yubihsm2.as_ref()
162 && let Some(mapping) = yubihsm2_config
163 .mappings()
164 .iter()
165 .find(|mapping| mapping.system_user_id().is_some_and(|id| id == user))
166 {
167 return Some(UserBackendConnection::YubiHsm2 {
168 admin_secret_handling: *self.system.admin_secret_handling(),
169 non_admin_secret_handling: *self.system.non_admin_secret_handling(),
170 connections: yubihsm2_config.connections().clone(),
171 mapping: mapping.clone(),
172 });
173 }
174
175 None
176 }
177
178 pub fn user_backend_connections(
186 &self,
187 filters: &[UserBackendConnectionFilter],
188 ) -> Vec<UserBackendConnection> {
189 let mut user_backend_connections = Vec::new();
190
191 if let Some(nethsm_config) = &self.nethsm
192 && (filters.is_empty()
193 || filters.contains(&UserBackendConnectionFilter::Backend(BackendType::NetHsm))
194 || !filters
195 .iter()
196 .any(|filter| matches!(filter, UserBackendConnectionFilter::Backend(_))))
197 {
198 let mappings = nethsm_config
199 .mappings()
200 .iter()
201 .filter(|mapping| {
202 filters.is_empty()
203 || matches!(filters, &[UserBackendConnectionFilter::Backend(_)])
204 || (matches!(mapping, NetHsmUserMapping::Admin(_))
205 && filters.contains(&UserBackendConnectionFilter::Admin))
206 || match mapping {
207 NetHsmUserMapping::Backup { .. }
208 | NetHsmUserMapping::CertificateRetrieval { .. }
209 | NetHsmUserMapping::HermeticMetrics { .. }
210 | NetHsmUserMapping::Metrics { .. }
211 | NetHsmUserMapping::Signing { .. } => {
212 filters.contains(&UserBackendConnectionFilter::NonAdmin)
213 }
214 NetHsmUserMapping::Admin(_) => false,
215 }
216 })
217 .collect::<Vec<_>>();
218 for mapping in mappings {
219 user_backend_connections.push(UserBackendConnection::NetHsm {
220 admin_secret_handling: *self.system.admin_secret_handling(),
221 non_admin_secret_handling: *self.system.non_admin_secret_handling(),
222 connections: nethsm_config.connections().clone(),
223 mapping: mapping.clone(),
224 });
225 }
226 }
227
228 if let Some(yubihsm2_config) = &self.yubihsm2
229 && (filters.is_empty()
230 || filters.contains(&UserBackendConnectionFilter::Backend(BackendType::YubiHsm2))
231 || !filters
232 .iter()
233 .any(|filter| matches!(filter, UserBackendConnectionFilter::Backend(_))))
234 {
235 let mappings = yubihsm2_config
236 .mappings()
237 .iter()
238 .filter(|mapping| {
239 filters.is_empty()
240 || matches!(filters, &[UserBackendConnectionFilter::Backend(_)])
241 || (matches!(mapping, YubiHsm2UserMapping::Admin { .. })
242 && filters.contains(&UserBackendConnectionFilter::Admin))
243 || match mapping {
244 YubiHsm2UserMapping::AuditLog { .. }
245 | YubiHsm2UserMapping::Backup { .. }
246 | YubiHsm2UserMapping::CertificateRetrieval { .. }
247 | YubiHsm2UserMapping::HermeticAuditLog { .. }
248 | YubiHsm2UserMapping::Signing { .. } => {
249 filters.contains(&UserBackendConnectionFilter::NonAdmin)
250 }
251 YubiHsm2UserMapping::Admin { .. } => false,
252 }
253 })
254 .collect::<Vec<_>>();
255 for mapping in mappings {
256 user_backend_connections.push(UserBackendConnection::YubiHsm2 {
257 admin_secret_handling: *self.system.admin_secret_handling(),
258 non_admin_secret_handling: *self.system.non_admin_secret_handling(),
259 connections: yubihsm2_config.connections().clone(),
260 mapping: mapping.clone(),
261 });
262 }
263 }
264
265 user_backend_connections
266 }
267}
268
269impl ConfigAuthorizedKeyEntries for Config {
270 fn authorized_key_entries(&self) -> HashSet<&AuthorizedKeyEntry> {
271 let mut output = self.system.authorized_key_entries();
272 if let Some(nethsm) = &self.nethsm {
273 output.extend(nethsm.authorized_key_entries());
274 }
275 if let Some(yubihsm2) = &self.yubihsm2 {
276 output.extend(yubihsm2.authorized_key_entries());
277 }
278
279 output
280 }
281}
282
283impl<'a> ConfigSystemUserData<'a> for Config {
284 fn system_user_data(&'a self) -> HashSet<SystemUserData<'a>> {
285 let mut output = HashSet::new();
286
287 for mapping in self.system.mappings() {
288 output.insert(mapping.into());
289 }
290
291 if let Some(config) = self.nethsm() {
292 for mapping in config.mappings() {
293 output.insert(mapping.into());
294 }
295 }
296
297 if let Some(config) = self.yubihsm2() {
298 for mapping in config.mappings() {
299 output.insert(mapping.into());
300 }
301 }
302
303 output
304 }
305}
306
307impl ConfigSystemUserIds for Config {
308 fn system_user_ids(&self) -> HashSet<&SystemUserId> {
309 let mut output = self.system.system_user_ids();
310 if let Some(nethsm) = &self.nethsm {
311 output.extend(nethsm.system_user_ids());
312 }
313 if let Some(yubihsm2) = &self.yubihsm2 {
314 output.extend(yubihsm2.system_user_ids());
315 }
316
317 output
318 }
319}
320
321impl ConfigBuilder {
322 pub fn new(system: SystemConfig) -> Self {
324 Self(Config {
325 system,
326 nethsm: None,
327 yubihsm2: None,
328 })
329 }
330}