aboutsummaryrefslogtreecommitdiffstats
path: root/src/cmd/server.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/server.rs')
-rw-r--r--src/cmd/server.rs185
1 files changed, 112 insertions, 73 deletions
diff --git a/src/cmd/server.rs b/src/cmd/server.rs
index be70da6..ae96a86 100644
--- a/src/cmd/server.rs
+++ b/src/cmd/server.rs
@@ -2,6 +2,116 @@ use crate::prelude::*;
use std::convert::TryFrom as _;
use std::io::Read as _;
+#[derive(serde::Deserialize)]
+pub struct Config {
+ #[serde(
+ deserialize_with = "crate::config::listen_address",
+ default = "crate::config::default_listen_address"
+ )]
+ address: std::net::SocketAddr,
+
+ #[serde(default = "crate::config::default_connection_buffer_size")]
+ buffer_size: usize,
+
+ #[serde(default = "crate::config::default_read_timeout")]
+ read_timeout: std::time::Duration,
+
+ tls_identity_file: Option<String>,
+
+ #[serde(
+ deserialize_with = "crate::config::allowed_login_methods",
+ default = "crate::config::default_allowed_login_methods"
+ )]
+ allowed_login_methods:
+ std::collections::HashSet<crate::protocol::AuthType>,
+}
+
+impl crate::config::Config for Config {
+ fn merge_args<'a>(
+ &mut self,
+ matches: &clap::ArgMatches<'a>,
+ ) -> Result<()> {
+ if matches.is_present("address") {
+ self.address = matches
+ .value_of("address")
+ .unwrap()
+ .parse()
+ .context(crate::error::ParseAddr)?;
+ }
+ if matches.is_present("buffer-size") {
+ let s = matches.value_of("buffer-size").unwrap();
+ self.buffer_size = s
+ .parse()
+ .context(crate::error::ParseBufferSize { input: s })?;
+ }
+ if matches.is_present("read-timeout") {
+ let s = matches.value_of("read-timeout").unwrap();
+ self.read_timeout = s
+ .parse()
+ .map(std::time::Duration::from_secs)
+ .context(crate::error::ParseReadTimeout { input: s })?;
+ }
+ if matches.is_present("tls-identity-file") {
+ self.tls_identity_file = Some(
+ matches.value_of("tls-identity-file").unwrap().to_string(),
+ );
+ }
+ if matches.is_present("allowed-login-methods") {
+ self.allowed_login_methods = matches
+ .values_of("allowed-login-methods")
+ .unwrap()
+ .map(crate::protocol::AuthType::try_from)
+ .collect::<Result<
+ std::collections::HashSet<crate::protocol::AuthType>,
+ >>()?;
+ }
+ Ok(())
+ }
+
+ fn run(&self) -> Result<()> {
+ let (acceptor, server) =
+ if let Some(tls_identity_file) = &self.tls_identity_file {
+ create_server_tls(
+ self.address,
+ self.buffer_size,
+ self.read_timeout,
+ tls_identity_file,
+ self.allowed_login_methods.clone(),
+ )?
+ } else {
+ create_server(
+ self.address,
+ self.buffer_size,
+ self.read_timeout,
+ self.allowed_login_methods.clone(),
+ )?
+ };
+ tokio::run(futures::future::lazy(move || {
+ tokio::spawn(server.map_err(|e| {
+ eprintln!("{}", e);
+ }));
+
+ acceptor.map_err(|e| {
+ eprintln!("{}", e);
+ })
+ }));
+ Ok(())
+ }
+}
+
+impl Default for Config {
+ fn default() -> Self {
+ Self {
+ address: crate::config::default_listen_address(),
+ buffer_size: crate::config::default_connection_buffer_size(),
+ read_timeout: crate::config::default_read_timeout(),
+ tls_identity_file: None,
+ allowed_login_methods:
+ crate::config::default_allowed_login_methods(),
+ }
+ }
+}
+
pub fn cmd<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> {
app.about("Run a teleterm server")
.arg(
@@ -32,79 +142,8 @@ pub fn cmd<'a, 'b>(app: clap::App<'a, 'b>) -> clap::App<'a, 'b> {
)
}
-pub fn run<'a>(matches: &clap::ArgMatches<'a>) -> super::Result<()> {
- let address = matches.value_of("address").map_or_else(
- || Ok("0.0.0.0:4144".parse().unwrap()),
- |s| s.parse().context(crate::error::ParseAddr),
- )?;
- let buffer_size =
- matches
- .value_of("buffer-size")
- .map_or(Ok(4 * 1024 * 1024), |s| {
- s.parse()
- .context(crate::error::ParseBufferSize { input: s })
- })?;
- let read_timeout = matches.value_of("read-timeout").map_or(
- Ok(std::time::Duration::from_secs(120)),
- |s| {
- s.parse()
- .map(std::time::Duration::from_secs)
- .context(crate::error::ParseReadTimeout { input: s })
- },
- )?;
- let tls_identity_file = matches.value_of("tls-identity-file");
- let allowed_login_methods =
- matches.values_of("allowed-login-methods").map_or_else(
- || Ok(crate::protocol::AuthType::iter().collect()),
- |methods| {
- methods.map(crate::protocol::AuthType::try_from).collect()
- },
- )?;
- run_impl(
- address,
- buffer_size,
- read_timeout,
- tls_identity_file,
- allowed_login_methods,
- )
-}
-
-fn run_impl(
- address: std::net::SocketAddr,
- buffer_size: usize,
- read_timeout: std::time::Duration,
- tls_identity_file: Option<&str>,
- allowed_login_methods: std::collections::HashSet<
- crate::protocol::AuthType,
- >,
-) -> Result<()> {
- let (acceptor, server) =
- if let Some(tls_identity_file) = tls_identity_file {
- create_server_tls(
- address,
- buffer_size,
- read_timeout,
- tls_identity_file,
- allowed_login_methods,
- )?
- } else {
- create_server(
- address,
- buffer_size,
- read_timeout,
- allowed_login_methods,
- )?
- };
- tokio::run(futures::future::lazy(move || {
- tokio::spawn(server.map_err(|e| {
- eprintln!("{}", e);
- }));
-
- acceptor.map_err(|e| {
- eprintln!("{}", e);
- })
- }));
- Ok(())
+pub fn config() -> Box<dyn crate::config::Config> {
+ Box::new(Config::default())
}
fn create_server(