1 //! An RPKI publication protocol server.
2 use std::{collections::HashMap, path::PathBuf, sync::Arc};
3 
4 use bytes::Bytes;
5 use chrono::Duration;
6 
7 use rpki::{repository::cert::Cert, uri};
8 
9 use crate::{
10     commons::{
11         actor::{Actor, ActorDef},
12         api::{
13             AddChildRequest, AllCertAuthIssues, AspaCustomer, AspaDefinitionList, AspaDefinitionUpdates,
14             AspaProvidersUpdate, CaCommandDetails, CaRepoDetails, CertAuthInfo, CertAuthInit, CertAuthIssues,
15             CertAuthList, CertAuthStats, ChildCaInfo, ChildHandle, ChildrenConnectionStats, CommandHistory,
16             CommandHistoryCriteria, Handle, ListReply, ParentCaContact, ParentCaReq, ParentHandle,
17             PublicationServerUris, PublishDelta, PublisherDetails, PublisherHandle, RepositoryContact, ResourceSet,
18             RoaDefinition, RoaDefinitionUpdates, RtaList, RtaName, RtaPrepResponse, ServerInfo, TaCertDetails,
19             Timestamp, UpdateChildRequest,
20         },
21         bgp::{BgpAnalyser, BgpAnalysisReport, BgpAnalysisSuggestion},
22         crypto::KrillSigner,
23         eventsourcing::CommandKey,
24         remote::rfc8183,
25         KrillEmptyResult, KrillResult,
26     },
27     constants::*,
28     daemon::{
29         auth::{providers::AdminTokenAuthProvider, Authorizer, LoggedInUser},
30         ca::{
31             self, ta_handle, testbed_ca_handle, CaStatus, ResourceTaggedAttestation, RouteAuthorizationUpdates,
32             RtaContentRequest, RtaPrepareRequest,
33         },
34         config::{AuthType, Config},
35         http::HttpResponse,
36         mq::MessageQueue,
37         scheduler::Scheduler,
38     },
39     pubd::{RepoStats, RepositoryManager},
40 };
41 
42 #[cfg(feature = "multi-user")]
43 use crate::daemon::auth::{
44     common::session::LoginSessionCache,
45     providers::{ConfigFileAuthProvider, OpenIDConnectAuthProvider},
46 };
47 
48 //------------ KrillServer ---------------------------------------------------
49 
50 /// This is the krill server that is doing all the orchestration for all components.
51 pub struct KrillServer {
52     // The base URI for this service
53     service_uri: uri::Https,
54 
55     // The base working directory, used for various storage
56     work_dir: PathBuf,
57 
58     // Component responsible for API authorization checks
59     authorizer: Authorizer,
60 
61     // Publication server, with configured publishers
62     repo_manager: Arc<RepositoryManager>,
63 
64     // Handles the internal TA and/or CAs
65     ca_manager: Arc<ca::CaManager>,
66 
67     // Handles the internal TA and/or CAs
68     bgp_analyser: Arc<BgpAnalyser>,
69 
70     // Responsible for background tasks, e.g. re-publishing
71     #[allow(dead_code)] // just need to keep this in scope
72     scheduler: Scheduler,
73 
74     // Time this server was started
75     started: Timestamp,
76 
77     #[cfg(feature = "multi-user")]
78     // Global login session cache
79     login_session_cache: Arc<LoginSessionCache>,
80 
81     // System actor
82     system_actor: Actor,
83 
84     pub config: Arc<Config>,
85 }
86 
87 /// # Set up and initialization
88 impl KrillServer {
89     /// Creates a new publication server. Note that state is preserved
90     /// on disk in the work_dir provided.
build(config: Arc<Config>) -> KrillResult<Self>91     pub async fn build(config: Arc<Config>) -> KrillResult<Self> {
92         let work_dir = &config.data_dir;
93         let service_uri = config.service_uri();
94 
95         info!("Starting {} v{}", KRILL_SERVER_APP, KRILL_VERSION);
96         info!("{} uses service uri: {}", KRILL_SERVER_APP, service_uri);
97 
98         if config.testbed().is_some() {
99             info!("Enabling TESTBED mode - ONLY USE THIS FOR TESTING AND TRAINING!");
100         }
101 
102         let mut repo_dir = work_dir.clone();
103         repo_dir.push("repo");
104 
105         let signer = Arc::new(KrillSigner::build(work_dir)?);
106 
107         #[cfg(feature = "multi-user")]
108         let login_session_cache = Arc::new(LoginSessionCache::new());
109 
110         // Construct the authorizer used to verify API access requests and to
111         // tell Lagosta where to send end-users to login and logout.
112         // TODO: remove the ugly duplication, however attempts to do so have so
113         // far failed due to incompatible match arm types, or unknown size of
114         // dyn AuthProvider, or concrete type needs to be known in async fn,
115         // etc.
116         let authorizer = match config.auth_type {
117             AuthType::AdminToken => {
118                 Authorizer::new(config.clone(), AdminTokenAuthProvider::new(config.clone()).into())?
119             }
120             #[cfg(feature = "multi-user")]
121             AuthType::ConfigFile => Authorizer::new(
122                 config.clone(),
123                 ConfigFileAuthProvider::new(config.clone(), login_session_cache.clone())?.into(),
124             )?,
125             #[cfg(feature = "multi-user")]
126             AuthType::OpenIDConnect => Authorizer::new(
127                 config.clone(),
128                 OpenIDConnectAuthProvider::new(config.clone(), login_session_cache.clone())?.into(),
129             )?,
130         };
131         let system_actor = authorizer.actor_from_def(ACTOR_DEF_KRILL);
132 
133         // for now, support that existing embedded repositories are still supported.
134         // this should be removed in future after people have had a chance to separate.
135         let repo_manager = Arc::new(RepositoryManager::build(config.clone(), signer.clone())?);
136 
137         // Used to have a shared queue for the caserver and the background job scheduler.
138         let event_queue = Arc::new(MessageQueue::default());
139 
140         let ca_manager = Arc::new(ca::CaManager::build(config.clone(), event_queue.clone(), signer).await?);
141 
142         ca_manager.resync_ca_statuses().await?;
143 
144         if let Some(testbed) = config.testbed() {
145             let uris = testbed.publication_server_uris();
146 
147             if !repo_manager.initialized()? {
148                 repo_manager.init(uris.clone())?;
149             }
150 
151             let ta_handle = ta_handle();
152             if !ca_manager.has_ca(&ta_handle)? {
153                 info!("Creating embedded Trust Anchor");
154 
155                 let ta_uri = testbed.ta_uri().clone();
156                 let ta_aia = testbed.ta_aia().clone();
157 
158                 // Add TA and add as publisher
159                 ca_manager
160                     .init_ta(ta_aia, vec![ta_uri], &repo_manager, &system_actor)
161                     .await?;
162 
163                 let testbed_ca_handle = testbed_ca_handle();
164                 if !ca_manager.has_ca(&testbed_ca_handle)? {
165                     info!("Creating embedded Testbed CA");
166 
167                     // Add the new testbed CA
168                     ca_manager.init_ca(&testbed_ca_handle)?;
169                     let testbed_ca = ca_manager.get_ca(&testbed_ca_handle).await?;
170 
171                     // Add the new testbed publisher
172                     let pub_req =
173                         rfc8183::PublisherRequest::new(None, testbed_ca_handle.clone(), testbed_ca.id_cert().clone());
174                     repo_manager.create_publisher(pub_req, &system_actor)?;
175 
176                     let repo_response = repo_manager.repository_response(&testbed_ca_handle)?;
177                     let repo_contact = RepositoryContact::new(repo_response);
178                     ca_manager
179                         .update_repo(testbed_ca_handle.clone(), repo_contact, false, &system_actor)
180                         .await?;
181 
182                     // Establish the TA (parent) <-> testbed CA (child) relationship
183                     let testbed_ca_resources = ResourceSet::all_resources();
184 
185                     let (_, _, child_id_cert) = testbed_ca.child_request().unpack();
186 
187                     let child_req =
188                         AddChildRequest::new(testbed_ca_handle.clone(), testbed_ca_resources, child_id_cert);
189                     let parent_ca_contact = ca_manager
190                         .ca_add_child(&ta_handle, child_req, &service_uri, &system_actor)
191                         .await?;
192                     let parent_req = ParentCaReq::new(ta_handle.clone(), parent_ca_contact);
193                     ca_manager
194                         .ca_parent_add_or_update(testbed_ca_handle, parent_req, &system_actor)
195                         .await?;
196                 }
197             }
198         }
199 
200         let bgp_analyser = Arc::new(BgpAnalyser::new(
201             config.bgp_risdumps_enabled,
202             &config.bgp_risdumps_v4_uri,
203             &config.bgp_risdumps_v6_uri,
204         ));
205 
206         let scheduler = Scheduler::build(
207             event_queue,
208             ca_manager.clone(),
209             bgp_analyser.clone(),
210             #[cfg(feature = "multi-user")]
211             login_session_cache.clone(),
212             &config,
213             &system_actor,
214         );
215 
216         Ok(KrillServer {
217             service_uri,
218             work_dir: work_dir.clone(),
219             authorizer,
220             repo_manager,
221             ca_manager,
222             bgp_analyser,
223             scheduler,
224             started: Timestamp::now(),
225             #[cfg(feature = "multi-user")]
226             login_session_cache,
227             system_actor,
228             config,
229         })
230     }
231 
service_base_uri(&self) -> &uri::Https232     pub fn service_base_uri(&self) -> &uri::Https {
233         &self.service_uri
234     }
235 
server_info(&self) -> ServerInfo236     pub fn server_info(&self) -> ServerInfo {
237         ServerInfo::new(KRILL_VERSION, self.started)
238     }
239 }
240 
241 /// # Authentication and Access
242 impl KrillServer {
system_actor(&self) -> &Actor243     pub fn system_actor(&self) -> &Actor {
244         &self.system_actor
245     }
246 
actor_from_request(&self, request: &hyper::Request<hyper::Body>) -> Actor247     pub async fn actor_from_request(&self, request: &hyper::Request<hyper::Body>) -> Actor {
248         self.authorizer.actor_from_request(request).await
249     }
250 
actor_from_def(&self, actor_def: ActorDef) -> Actor251     pub fn actor_from_def(&self, actor_def: ActorDef) -> Actor {
252         self.authorizer.actor_from_def(actor_def)
253     }
254 
get_login_url(&self) -> KrillResult<HttpResponse>255     pub async fn get_login_url(&self) -> KrillResult<HttpResponse> {
256         self.authorizer.get_login_url().await
257     }
258 
login(&self, request: &hyper::Request<hyper::Body>) -> KrillResult<LoggedInUser>259     pub async fn login(&self, request: &hyper::Request<hyper::Body>) -> KrillResult<LoggedInUser> {
260         self.authorizer.login(request).await
261     }
262 
logout(&self, request: &hyper::Request<hyper::Body>) -> KrillResult<HttpResponse>263     pub async fn logout(&self, request: &hyper::Request<hyper::Body>) -> KrillResult<HttpResponse> {
264         self.authorizer.logout(request).await
265     }
266 
testbed_enabled(&self) -> bool267     pub fn testbed_enabled(&self) -> bool {
268         self.ca_manager.testbed_enabled()
269     }
270 
271     #[cfg(feature = "multi-user")]
login_session_cache_size(&self) -> usize272     pub fn login_session_cache_size(&self) -> usize {
273         self.login_session_cache.size()
274     }
275 }
276 
277 /// # Configure publishers
278 impl KrillServer {
279     /// Returns the repository server stats
repo_stats(&self) -> KrillResult<RepoStats>280     pub fn repo_stats(&self) -> KrillResult<RepoStats> {
281         self.repo_manager.repo_stats()
282     }
283 
284     /// Returns all current publishers.
publishers(&self) -> KrillResult<Vec<Handle>>285     pub fn publishers(&self) -> KrillResult<Vec<Handle>> {
286         self.repo_manager.publishers()
287     }
288 
289     /// Adds the publishers, blows up if it already existed.
add_publisher( &self, req: rfc8183::PublisherRequest, actor: &Actor, ) -> KrillResult<rfc8183::RepositoryResponse>290     pub fn add_publisher(
291         &self,
292         req: rfc8183::PublisherRequest,
293         actor: &Actor,
294     ) -> KrillResult<rfc8183::RepositoryResponse> {
295         let publisher_handle = req.publisher_handle().clone();
296         self.repo_manager.create_publisher(req, actor)?;
297         self.repository_response(&publisher_handle)
298     }
299 
300     /// Removes a publisher, blows up if it didn't exist.
remove_publisher(&self, publisher: PublisherHandle, actor: &Actor) -> KrillEmptyResult301     pub fn remove_publisher(&self, publisher: PublisherHandle, actor: &Actor) -> KrillEmptyResult {
302         self.repo_manager.remove_publisher(publisher, actor)
303     }
304 
305     /// Returns a publisher.
get_publisher(&self, publisher: &PublisherHandle) -> KrillResult<PublisherDetails>306     pub fn get_publisher(&self, publisher: &PublisherHandle) -> KrillResult<PublisherDetails> {
307         self.repo_manager.get_publisher_details(publisher)
308     }
309 
rrdp_base_path(&self) -> PathBuf310     pub fn rrdp_base_path(&self) -> PathBuf {
311         let mut path = self.work_dir.clone();
312         path.push("repo/rrdp");
313         path
314     }
315 }
316 
317 /// # Manage RFC8181 clients
318 ///
319 impl KrillServer {
repository_response(&self, publisher: &PublisherHandle) -> KrillResult<rfc8183::RepositoryResponse>320     pub fn repository_response(&self, publisher: &PublisherHandle) -> KrillResult<rfc8183::RepositoryResponse> {
321         self.repo_manager.repository_response(publisher)
322     }
323 
rfc8181(&self, publisher: PublisherHandle, msg_bytes: Bytes) -> KrillResult<Bytes>324     pub fn rfc8181(&self, publisher: PublisherHandle, msg_bytes: Bytes) -> KrillResult<Bytes> {
325         self.repo_manager.rfc8181(publisher, msg_bytes)
326     }
327 }
328 
329 /// # Being a parent
330 ///
331 impl KrillServer {
ta(&self) -> KrillResult<TaCertDetails>332     pub async fn ta(&self) -> KrillResult<TaCertDetails> {
333         let ta = self.ca_manager.get_ca(&ta_handle()).await?;
334         if let ParentCaContact::Ta(ta) = ta.parent(&ta_handle()).unwrap() {
335             Ok(ta.clone())
336         } else {
337             panic!("Found TA which was not initialized as TA.")
338         }
339     }
340 
trust_anchor_cert(&self) -> Option<Cert>341     pub async fn trust_anchor_cert(&self) -> Option<Cert> {
342         self.ta().await.ok().map(|details| details.cert().clone())
343     }
344 
345     /// Adds a child to a CA and returns the ParentCaInfo that the child
346     /// will need to contact this CA for resource requests.
ca_add_child( &self, parent: &ParentHandle, req: AddChildRequest, actor: &Actor, ) -> KrillResult<ParentCaContact>347     pub async fn ca_add_child(
348         &self,
349         parent: &ParentHandle,
350         req: AddChildRequest,
351         actor: &Actor,
352     ) -> KrillResult<ParentCaContact> {
353         let contact = self
354             .ca_manager
355             .ca_add_child(parent, req, &self.service_uri, actor)
356             .await?;
357         Ok(contact)
358     }
359 
360     /// Shows the parent contact for a child.
ca_parent_contact(&self, parent: &ParentHandle, child: ChildHandle) -> KrillResult<ParentCaContact>361     pub async fn ca_parent_contact(&self, parent: &ParentHandle, child: ChildHandle) -> KrillResult<ParentCaContact> {
362         let contact = self
363             .ca_manager
364             .ca_parent_contact(parent, child, &self.service_uri)
365             .await?;
366         Ok(contact)
367     }
368 
369     /// Shows the parent contact for a child.
ca_parent_response( &self, parent: &ParentHandle, child: ChildHandle, ) -> KrillResult<rfc8183::ParentResponse>370     pub async fn ca_parent_response(
371         &self,
372         parent: &ParentHandle,
373         child: ChildHandle,
374     ) -> KrillResult<rfc8183::ParentResponse> {
375         let contact = self
376             .ca_manager
377             .ca_parent_response(parent, child, &self.service_uri)
378             .await?;
379         Ok(contact)
380     }
381 
382     /// Update IdCert or resources of a child.
ca_child_update( &self, parent: &ParentHandle, child: ChildHandle, req: UpdateChildRequest, actor: &Actor, ) -> KrillEmptyResult383     pub async fn ca_child_update(
384         &self,
385         parent: &ParentHandle,
386         child: ChildHandle,
387         req: UpdateChildRequest,
388         actor: &Actor,
389     ) -> KrillEmptyResult {
390         self.ca_manager.ca_child_update(parent, child, req, actor).await?;
391         Ok(())
392     }
393 
394     /// Update IdCert or resources of a child.
ca_child_remove(&self, handle: &Handle, child: ChildHandle, actor: &Actor) -> KrillEmptyResult395     pub async fn ca_child_remove(&self, handle: &Handle, child: ChildHandle, actor: &Actor) -> KrillEmptyResult {
396         self.ca_manager.ca_child_remove(handle, child, actor).await?;
397         Ok(())
398     }
399 
400     /// Show details for a child under the CA.
ca_child_show(&self, ca: &Handle, child: &ChildHandle) -> KrillResult<ChildCaInfo>401     pub async fn ca_child_show(&self, ca: &Handle, child: &ChildHandle) -> KrillResult<ChildCaInfo> {
402         let child = self.ca_manager.ca_show_child(ca, child).await?;
403         Ok(child)
404     }
405 
406     /// Show children stats under the CA.
ca_stats_child_connections(&self, ca: &Handle) -> KrillResult<ChildrenConnectionStats>407     pub async fn ca_stats_child_connections(&self, ca: &Handle) -> KrillResult<ChildrenConnectionStats> {
408         self.ca_manager
409             .get_ca_status(ca)
410             .await
411             .map(|status| status.get_children_connection_stats())
412     }
413 }
414 
415 /// # Being a child
416 ///
417 impl KrillServer {
418     /// Returns the child request for a CA, or NONE if the CA cannot be found.
ca_child_req(&self, handle: &Handle) -> KrillResult<rfc8183::ChildRequest>419     pub async fn ca_child_req(&self, handle: &Handle) -> KrillResult<rfc8183::ChildRequest> {
420         self.ca_manager.get_ca(handle).await.map(|ca| ca.child_request())
421     }
422 
423     /// Updates a parent contact for a CA
ca_parent_add_or_update( &self, ca: Handle, parent_req: ParentCaReq, actor: &Actor, ) -> KrillEmptyResult424     pub async fn ca_parent_add_or_update(
425         &self,
426         ca: Handle,
427         parent_req: ParentCaReq,
428         actor: &Actor,
429     ) -> KrillEmptyResult {
430         let parent = parent_req.handle();
431         let contact = parent_req.contact();
432         self.ca_manager
433             .get_entitlements_from_contact(&ca, parent, contact, false)
434             .await?;
435 
436         Ok(self.ca_manager.ca_parent_add_or_update(ca, parent_req, actor).await?)
437     }
438 
ca_parent_remove(&self, handle: Handle, parent: ParentHandle, actor: &Actor) -> KrillEmptyResult439     pub async fn ca_parent_remove(&self, handle: Handle, parent: ParentHandle, actor: &Actor) -> KrillEmptyResult {
440         Ok(self.ca_manager.ca_parent_remove(handle, parent, actor).await?)
441     }
442 
ca_parent_revoke(&self, handle: &Handle, parent: &ParentHandle) -> KrillEmptyResult443     pub async fn ca_parent_revoke(&self, handle: &Handle, parent: &ParentHandle) -> KrillEmptyResult {
444         Ok(self.ca_manager.ca_parent_revoke(handle, parent).await?)
445     }
446 }
447 
448 /// # Stats and status of CAS
449 ///
450 impl KrillServer {
cas_stats(&self) -> KrillResult<HashMap<Handle, CertAuthStats>>451     pub async fn cas_stats(&self) -> KrillResult<HashMap<Handle, CertAuthStats>> {
452         let mut res = HashMap::new();
453 
454         for ca in self.ca_list(&self.system_actor)?.cas() {
455             // can't fail really, but to be sure
456             if let Ok(ca) = self.ca_manager.get_ca(ca.handle()).await {
457                 let roas = ca.roa_definitions();
458                 let roa_count = roas.len();
459                 let child_count = ca.children().count();
460 
461                 let bgp_report = if ca.handle().as_str() == "ta" || ca.handle().as_str() == "testbed" {
462                     BgpAnalysisReport::new(vec![])
463                 } else {
464                     self.bgp_analyser
465                         .analyse(roas.as_slice(), &ca.all_resources(), None)
466                         .await
467                 };
468 
469                 res.insert(
470                     ca.handle().clone(),
471                     CertAuthStats::new(roa_count, child_count, bgp_report.into()),
472                 );
473             }
474         }
475 
476         Ok(res)
477     }
478 
all_ca_issues(&self, actor: &Actor) -> KrillResult<AllCertAuthIssues>479     pub async fn all_ca_issues(&self, actor: &Actor) -> KrillResult<AllCertAuthIssues> {
480         let mut all_issues = AllCertAuthIssues::default();
481         for ca in self.ca_list(actor)?.cas() {
482             let issues = self.ca_issues(ca.handle()).await?;
483             if !issues.is_empty() {
484                 all_issues.add(ca.handle().clone(), issues);
485             }
486         }
487 
488         Ok(all_issues)
489     }
490 
ca_issues(&self, ca_handle: &Handle) -> KrillResult<CertAuthIssues>491     pub async fn ca_issues(&self, ca_handle: &Handle) -> KrillResult<CertAuthIssues> {
492         let mut issues = CertAuthIssues::default();
493 
494         let ca_status = self.ca_manager.get_ca_status(ca_handle).await?;
495 
496         if let Some(error) = ca_status.repo().to_failure_opt() {
497             issues.add_repo_issue(error)
498         }
499 
500         for (parent, status) in ca_status.parents().iter() {
501             if let Some(error) = status.to_failure_opt() {
502                 issues.add_parent_issue(parent.clone(), error)
503             }
504         }
505 
506         Ok(issues)
507     }
508 }
509 
510 /// # Synchronization operations for CAS
511 ///
512 impl KrillServer {
513     /// Republish all CAs that need it.
republish_all(&self) -> KrillEmptyResult514     pub async fn republish_all(&self) -> KrillEmptyResult {
515         self.ca_manager.republish_all().await?;
516         Ok(())
517     }
518 
519     /// Re-sync all CAs with their repositories
cas_repo_sync_all(&self, actor: &Actor) -> KrillEmptyResult520     pub async fn cas_repo_sync_all(&self, actor: &Actor) -> KrillEmptyResult {
521         self.ca_manager.cas_repo_sync_all(actor).await;
522         Ok(())
523     }
524 
525     /// Re-sync a specific CA with its repository
cas_repo_sync_single(&self, ca: &Handle) -> KrillEmptyResult526     pub async fn cas_repo_sync_single(&self, ca: &Handle) -> KrillEmptyResult {
527         self.ca_manager.cas_repo_sync_single(ca).await?;
528         Ok(())
529     }
530 
531     /// Refresh all CAs: ask for updates and shrink as needed.
cas_refresh_all(&self, actor: &Actor) -> KrillEmptyResult532     pub async fn cas_refresh_all(&self, actor: &Actor) -> KrillEmptyResult {
533         self.ca_manager.cas_refresh_all(self.started, actor).await;
534         Ok(())
535     }
536 
537     /// Refresh a specific CA with its parents
cas_refresh_single(&self, ca_handle: Handle, actor: &Actor) -> KrillEmptyResult538     pub async fn cas_refresh_single(&self, ca_handle: Handle, actor: &Actor) -> KrillEmptyResult {
539         self.ca_manager.cas_refresh_single(ca_handle, self.started, actor).await;
540         Ok(())
541     }
542 }
543 
544 /// # Admin CAS
545 ///
546 impl KrillServer {
ca_list(&self, actor: &Actor) -> KrillResult<CertAuthList>547     pub fn ca_list(&self, actor: &Actor) -> KrillResult<CertAuthList> {
548         self.ca_manager.ca_list(actor)
549     }
550 
551     /// Returns the public CA info for a CA, or NONE if the CA cannot be found.
ca_info(&self, handle: &Handle) -> KrillResult<CertAuthInfo>552     pub async fn ca_info(&self, handle: &Handle) -> KrillResult<CertAuthInfo> {
553         self.ca_manager.get_ca(handle).await.map(|ca| ca.as_ca_info())
554     }
555 
556     /// Returns the CA status, or an error if none can be found.
ca_status(&self, ca: &Handle) -> KrillResult<Arc<CaStatus>>557     pub async fn ca_status(&self, ca: &Handle) -> KrillResult<Arc<CaStatus>> {
558         self.ca_manager.get_ca_status(ca).await
559     }
560 
561     /// Delete a CA. Let it do best effort revocation requests and withdraw
562     /// all its objects first. Note that any children of this CA will be left
563     /// orphaned, and they will only learn of this sad fact when they choose
564     /// to call home.
ca_delete(&self, ca_handle: &Handle, actor: &Actor) -> KrillResult<()>565     pub async fn ca_delete(&self, ca_handle: &Handle, actor: &Actor) -> KrillResult<()> {
566         self.ca_manager.delete_ca(ca_handle, actor).await
567     }
568 
569     /// Returns the parent contact for a CA and parent, or NONE if either the CA or the parent cannot be found.
ca_my_parent_contact(&self, handle: &Handle, parent: &ParentHandle) -> KrillResult<ParentCaContact>570     pub async fn ca_my_parent_contact(&self, handle: &Handle, parent: &ParentHandle) -> KrillResult<ParentCaContact> {
571         let ca = self.ca_manager.get_ca(handle).await?;
572         ca.parent(parent).map(|p| p.clone())
573     }
574 
575     /// Returns the history for a CA.
ca_history(&self, handle: &Handle, crit: CommandHistoryCriteria) -> KrillResult<CommandHistory>576     pub async fn ca_history(&self, handle: &Handle, crit: CommandHistoryCriteria) -> KrillResult<CommandHistory> {
577         self.ca_manager.ca_history(handle, crit).await
578     }
579 
ca_command_details(&self, handle: &Handle, command: CommandKey) -> KrillResult<CaCommandDetails>580     pub fn ca_command_details(&self, handle: &Handle, command: CommandKey) -> KrillResult<CaCommandDetails> {
581         self.ca_manager.ca_command_details(handle, command)
582     }
583 
584     /// Returns the publisher request for a CA, or NONE of the CA cannot be found.
ca_publisher_req(&self, handle: &Handle) -> KrillResult<rfc8183::PublisherRequest>585     pub async fn ca_publisher_req(&self, handle: &Handle) -> KrillResult<rfc8183::PublisherRequest> {
586         self.ca_manager.get_ca(handle).await.map(|ca| ca.publisher_request())
587     }
588 
ca_init(&self, init: CertAuthInit) -> KrillEmptyResult589     pub fn ca_init(&self, init: CertAuthInit) -> KrillEmptyResult {
590         let handle = init.unpack();
591         self.ca_manager.init_ca(&handle)
592     }
593 
594     /// Return the info about the CONFIGured repository server for a given Ca.
595     /// and the actual objects published there, as reported by a list reply.
ca_repo_details(&self, handle: &Handle) -> KrillResult<CaRepoDetails>596     pub async fn ca_repo_details(&self, handle: &Handle) -> KrillResult<CaRepoDetails> {
597         let ca = self.ca_manager.get_ca(handle).await?;
598         let contact = ca.repository_contact()?;
599         Ok(CaRepoDetails::new(contact.clone()))
600     }
601 
602     /// Update the repository for a CA, or return an error. (see `CertAuth::repo_update`)
ca_repo_update(&self, handle: Handle, contact: RepositoryContact, actor: &Actor) -> KrillEmptyResult603     pub async fn ca_repo_update(&self, handle: Handle, contact: RepositoryContact, actor: &Actor) -> KrillEmptyResult {
604         Ok(self.ca_manager.update_repo(handle, contact, true, actor).await?)
605     }
606 
ca_update_id(&self, handle: Handle, actor: &Actor) -> KrillEmptyResult607     pub async fn ca_update_id(&self, handle: Handle, actor: &Actor) -> KrillEmptyResult {
608         Ok(self.ca_manager.ca_update_id(handle, actor).await?)
609     }
610 
ca_keyroll_init(&self, handle: Handle, actor: &Actor) -> KrillEmptyResult611     pub async fn ca_keyroll_init(&self, handle: Handle, actor: &Actor) -> KrillEmptyResult {
612         Ok(self
613             .ca_manager
614             .ca_keyroll_init(handle, Duration::seconds(0), actor)
615             .await?)
616     }
617 
ca_keyroll_activate(&self, handle: Handle, actor: &Actor) -> KrillEmptyResult618     pub async fn ca_keyroll_activate(&self, handle: Handle, actor: &Actor) -> KrillEmptyResult {
619         Ok(self
620             .ca_manager
621             .ca_keyroll_activate(handle, Duration::seconds(0), actor)
622             .await?)
623     }
624 
rfc6492( &self, handle: Handle, msg_bytes: Bytes, user_agent: Option<String>, actor: &Actor, ) -> KrillResult<Bytes>625     pub async fn rfc6492(
626         &self,
627         handle: Handle,
628         msg_bytes: Bytes,
629         user_agent: Option<String>,
630         actor: &Actor,
631     ) -> KrillResult<Bytes> {
632         Ok(self.ca_manager.rfc6492(&handle, msg_bytes, user_agent, actor).await?)
633     }
634 }
635 
636 /// # Handle ASPA requests
637 ///
638 impl KrillServer {
ca_aspas_definitions_show(&self, ca: Handle) -> KrillResult<AspaDefinitionList>639     pub async fn ca_aspas_definitions_show(&self, ca: Handle) -> KrillResult<AspaDefinitionList> {
640         Ok(self.ca_manager.ca_aspas_definitions_show(ca).await?)
641     }
642 
ca_aspas_definitions_update( &self, ca: Handle, updates: AspaDefinitionUpdates, actor: &Actor, ) -> KrillEmptyResult643     pub async fn ca_aspas_definitions_update(
644         &self,
645         ca: Handle,
646         updates: AspaDefinitionUpdates,
647         actor: &Actor,
648     ) -> KrillEmptyResult {
649         Ok(self.ca_manager.ca_aspas_definitions_update(ca, updates, actor).await?)
650     }
651 
ca_aspas_update_aspa( &self, ca: Handle, customer: AspaCustomer, update: AspaProvidersUpdate, actor: &Actor, ) -> KrillEmptyResult652     pub async fn ca_aspas_update_aspa(
653         &self,
654         ca: Handle,
655         customer: AspaCustomer,
656         update: AspaProvidersUpdate,
657         actor: &Actor,
658     ) -> KrillEmptyResult {
659         Ok(self
660             .ca_manager
661             .ca_aspas_update_aspa(ca, customer, update, actor)
662             .await?)
663     }
664 }
665 
666 /// # Handle route authorization requests
667 ///
668 impl KrillServer {
ca_routes_update( &self, handle: Handle, updates: RoaDefinitionUpdates, actor: &Actor, ) -> KrillEmptyResult669     pub async fn ca_routes_update(
670         &self,
671         handle: Handle,
672         updates: RoaDefinitionUpdates,
673         actor: &Actor,
674     ) -> KrillEmptyResult {
675         Ok(self.ca_manager.ca_routes_update(handle, updates.into(), actor).await?)
676     }
677 
ca_routes_show(&self, handle: &Handle) -> KrillResult<Vec<RoaDefinition>>678     pub async fn ca_routes_show(&self, handle: &Handle) -> KrillResult<Vec<RoaDefinition>> {
679         let ca = self.ca_manager.get_ca(handle).await?;
680         Ok(ca.roa_definitions())
681     }
682 
ca_routes_bgp_analysis(&self, handle: &Handle) -> KrillResult<BgpAnalysisReport>683     pub async fn ca_routes_bgp_analysis(&self, handle: &Handle) -> KrillResult<BgpAnalysisReport> {
684         let ca = self.ca_manager.get_ca(handle).await?;
685         let definitions = ca.roa_definitions();
686         let resources_held = ca.all_resources();
687         Ok(self
688             .bgp_analyser
689             .analyse(definitions.as_slice(), &resources_held, None)
690             .await)
691     }
692 
ca_routes_bgp_dry_run( &self, handle: &Handle, updates: RoaDefinitionUpdates, ) -> KrillResult<BgpAnalysisReport>693     pub async fn ca_routes_bgp_dry_run(
694         &self,
695         handle: &Handle,
696         updates: RoaDefinitionUpdates,
697     ) -> KrillResult<BgpAnalysisReport> {
698         let ca = self.ca_manager.get_ca(handle).await?;
699 
700         let updates: RouteAuthorizationUpdates = updates.into();
701         let updates = updates.into_explicit();
702         let resources_held = ca.all_resources();
703         let limit = Some(updates.affected_prefixes());
704 
705         let (would_be_routes, _) = ca.update_authorizations(&updates)?;
706         let roas: Vec<RoaDefinition> = would_be_routes
707             .into_authorizations()
708             .into_iter()
709             .map(|a| a.into())
710             .collect();
711 
712         Ok(self.bgp_analyser.analyse(roas.as_slice(), &resources_held, limit).await)
713     }
714 
ca_routes_bgp_suggest( &self, handle: &Handle, limit: Option<ResourceSet>, ) -> KrillResult<BgpAnalysisSuggestion>715     pub async fn ca_routes_bgp_suggest(
716         &self,
717         handle: &Handle,
718         limit: Option<ResourceSet>,
719     ) -> KrillResult<BgpAnalysisSuggestion> {
720         let ca = self.ca_manager.get_ca(handle).await?;
721         let definitions = ca.roa_definitions();
722         let resources_held = ca.all_resources();
723 
724         Ok(self
725             .bgp_analyser
726             .suggest(definitions.as_slice(), &resources_held, limit)
727             .await)
728     }
729 
730     /// Re-issue ROA objects so that they will use short subjects (see issue #700)
force_renew_roas(&self) -> KrillResult<()>731     pub async fn force_renew_roas(&self) -> KrillResult<()> {
732         self.ca_manager.force_renew_roas_all(self.system_actor()).await
733     }
734 }
735 
736 /// # Handle publication requests
737 ///
738 impl KrillServer {
739     /// Handles a publish delta request sent to the API, or.. through
740     /// the CmsProxy.
handle_delta(&self, publisher: PublisherHandle, delta: PublishDelta) -> KrillEmptyResult741     pub fn handle_delta(&self, publisher: PublisherHandle, delta: PublishDelta) -> KrillEmptyResult {
742         self.repo_manager.publish(publisher, delta)
743     }
744 
745     /// Handles a list request sent to the API, or.. through the CmsProxy.
handle_list(&self, publisher: &PublisherHandle) -> KrillResult<ListReply>746     pub fn handle_list(&self, publisher: &PublisherHandle) -> KrillResult<ListReply> {
747         self.repo_manager.list(publisher)
748     }
749 }
750 
751 /// # Handle Repository Server requests
752 ///
753 impl KrillServer {
754     /// Create the publication server, will fail if it was already created.
repository_init(&self, uris: PublicationServerUris) -> KrillResult<()>755     pub fn repository_init(&self, uris: PublicationServerUris) -> KrillResult<()> {
756         self.repo_manager.init(uris)
757     }
758 
759     /// Clear the publication server. Will fail if it still has publishers. Or if it does not exist
repository_clear(&self) -> KrillResult<()>760     pub fn repository_clear(&self) -> KrillResult<()> {
761         self.repo_manager.repository_clear()
762     }
763 
764     /// Perform an RRDP session reset. Useful after a restart of the server as we can never be
765     /// certain whether the previous state was the last public state seen by validators, or..
766     /// the server was started using a back up.
repository_session_reset(&self) -> KrillResult<()>767     pub fn repository_session_reset(&self) -> KrillResult<()> {
768         self.repo_manager.rrdp_session_reset()
769     }
770 }
771 
772 /// # Handle Resource Tagged Attestation requests
773 ///
774 impl KrillServer {
775     /// List all known RTAs
rta_list(&self, ca: Handle) -> KrillResult<RtaList>776     pub async fn rta_list(&self, ca: Handle) -> KrillResult<RtaList> {
777         let ca = self.ca_manager.get_ca(&ca).await?;
778         Ok(ca.rta_list())
779     }
780 
781     /// Show RTA
rta_show(&self, ca: Handle, name: RtaName) -> KrillResult<ResourceTaggedAttestation>782     pub async fn rta_show(&self, ca: Handle, name: RtaName) -> KrillResult<ResourceTaggedAttestation> {
783         let ca = self.ca_manager.get_ca(&ca).await?;
784         ca.rta_show(&name)
785     }
786 
787     /// Sign an RTA - either a new, or a prepared RTA
rta_sign( &self, ca: Handle, name: RtaName, request: RtaContentRequest, actor: &Actor, ) -> KrillResult<()>788     pub async fn rta_sign(
789         &self,
790         ca: Handle,
791         name: RtaName,
792         request: RtaContentRequest,
793         actor: &Actor,
794     ) -> KrillResult<()> {
795         self.ca_manager.rta_sign(ca, name, request, actor).await
796     }
797 
798     /// Prepare a multi
rta_multi_prep( &self, ca: Handle, name: RtaName, request: RtaPrepareRequest, actor: &Actor, ) -> KrillResult<RtaPrepResponse>799     pub async fn rta_multi_prep(
800         &self,
801         ca: Handle,
802         name: RtaName,
803         request: RtaPrepareRequest,
804         actor: &Actor,
805     ) -> KrillResult<RtaPrepResponse> {
806         self.ca_manager
807             .rta_multi_prep(&ca, name.clone(), request, actor)
808             .await?;
809         let ca = self.ca_manager.get_ca(&ca).await?;
810         ca.rta_prep_response(&name)
811     }
812 
813     /// Co-sign an existing RTA
rta_multi_cosign( &self, ca: Handle, name: RtaName, rta: ResourceTaggedAttestation, actor: &Actor, ) -> KrillResult<()>814     pub async fn rta_multi_cosign(
815         &self,
816         ca: Handle,
817         name: RtaName,
818         rta: ResourceTaggedAttestation,
819         actor: &Actor,
820     ) -> KrillResult<()> {
821         self.ca_manager.rta_multi_cosign(ca, name, rta, actor).await
822     }
823 }
824 
825 // Tested through integration tests
826