Skip to main content

enclave_runner/
builder.rs

1/* Copyright (c) Fortanix, Inc.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7use std::convert::TryInto;
8
9use crate::Command;
10use crate::platform::*;
11use crate::stream_router::{StreamRouter, OsStreamRouter};
12
13pub struct EnclaveBuilder<P: EnclavePlatform<T>, T: EnclaveType> {
14    platform: P,
15    stream_router: Option<Box<dyn StreamRouter + Send + Sync>>,
16    forward_panics: bool,
17    type_builder: T::ConfigurationBuilder,
18}
19
20impl<P: EnclavePlatform<T>, T: EnclaveType> EnclaveBuilder<P, T> {
21    pub fn new(platform: P) -> Self {
22        EnclaveBuilder {
23            platform,
24            stream_router: None,
25            forward_panics: false,
26            type_builder: Default::default(),
27        }
28    }
29
30    /// The stream router that this enclave should use when the enclave is
31    /// creating any streams. Defaults to [`OsStreamRouter`].
32    pub fn stream_router<R: Into<Box<dyn StreamRouter + Send + Sync>>>(&mut self, router: R) -> &mut Self {
33        self.stream_router = Some(router.into());
34        self
35    }
36
37    /// Whether to panic the runner if any enclave thread panics.
38    /// Defaults to `false`.
39    /// Note: If multiple enclaves are loaded, and an enclave with this set to
40    /// true panics, then all enclaves handled by this runner will exit because
41    /// the runner itself will panic.
42    pub fn forward_panics(&mut self, fp: bool) -> &mut Self {
43        self.forward_panics = fp;
44        self
45    }
46
47    pub fn build(self, loader: P::Loader) -> Result<T, anyhow::Error> {
48        let configuration = EnclaveConfiguration {
49            stream_router: self.stream_router.unwrap_or_else(|| OsStreamRouter::new()),
50            forward_panics: self.forward_panics,
51        };
52        self.platform.build(loader, configuration, self.type_builder.try_into()?)
53    }
54}
55
56impl<P: EnclavePlatform<Command>> EnclaveBuilder<P, Command> where {
57    /// Adds multiple arguments to pass to enclave's `fn main`.
58    /// **NOTE:** This is not an appropriate channel for passing secrets or
59    /// security configurations to the enclave.
60    pub fn args<I, S>(&mut self, args: I) -> &mut Self
61    where
62        I: IntoIterator<Item = S>,
63        S: AsRef<[u8]>,
64    {
65        let args = args.into_iter().map(|a| a.as_ref().to_owned());
66        self.type_builder.cmd_args.extend(args);
67        self
68    }
69
70    /// Adds an argument to pass to enclave's `fn main`.
71    /// **NOTE:** This is not an appropriate channel for passing secrets or
72    /// security configurations to the enclave.
73    pub fn arg<S: AsRef<[u8]>>(&mut self, arg: S) -> &mut Self {
74        let arg = arg.as_ref().to_owned();
75        self.type_builder.cmd_args.push(arg);
76        self
77    }
78
79    /// Sets the number of worker threads used to run the enclave.
80    pub fn num_worker_threads(&mut self, num_worker_threads: usize) -> &mut Self {
81        self.type_builder.num_worker_threads = Some(num_worker_threads);
82        self
83    }
84}