1
use std::path::PathBuf;
2

            
3
use clap::Subcommand;
4
use tokio::io::AsyncReadExt;
5

            
6
use crate::{Backend, BackendError, CustomServer};
7

            
8
/// Command to manage the server's certificates.
9
112
#[derive(Subcommand, Debug)]
10
pub enum Command {
11
    /// Installs a self-signed certificate into the server. The server can only
12
    /// have one global self-signed certificate. If `overwrite` is true, any
13
    /// existing certificate will be overwritten. If `overwrite` is false and a
14
    /// certificate already exists, an error is returned.
15
    InstallSelfSigned {
16
        /// If an existing certificate exists, an error will be returned unless
17
        /// `overwrite` is true.
18
        #[clap(short, long)]
19
        overwrite: bool,
20
    },
21
    /// Installs a X.509 certificate and associated private key in PEM format.
22
    ///
23
    /// This command reads the files `private_key` and `certificate` and
24
    /// executes
25
    /// [`Server::install_certificate()`](crate::CustomServer::install_certificate).
26
    Install {
27
        /// A private key used to generate `certificate` in the ASCII PEM format.
28
        private_key: PathBuf,
29
        /// The X.509 certificate chain in the ASCII PEM format.
30
        certificate_chain: PathBuf,
31
    },
32
}
33

            
34
impl Command {
35
    /// Executes the command.
36
1
    pub async fn execute<B: Backend>(
37
1
        &self,
38
1
        server: &CustomServer<B>,
39
1
    ) -> Result<(), BackendError<B::Error>> {
40
1
        match self {
41
1
            Self::InstallSelfSigned { overwrite } => {
42
10
                server.install_self_signed_certificate(*overwrite).await?;
43
            }
44
            Self::Install {
45
                private_key,
46
                certificate_chain,
47
            } => {
48
                let mut private_key_file = tokio::fs::File::open(&private_key).await?;
49
                let mut private_key = Vec::new();
50
                private_key_file.read_to_end(&mut private_key).await?;
51

            
52
                let mut certificate_chain_file = tokio::fs::File::open(&certificate_chain).await?;
53
                let mut certificate_chain = Vec::new();
54
                certificate_chain_file
55
                    .read_to_end(&mut certificate_chain)
56
                    .await?;
57

            
58
                server
59
                    .install_pem_certificate(&certificate_chain, &private_key)
60
                    .await?;
61
            }
62
        }
63

            
64
1
        Ok(())
65
1
    }
66
}