mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-25 16:17:56 +01:00
Splitting config
This commit is contained in:
parent
28d90f1078
commit
b02afe5575
@ -56,6 +56,7 @@ ptr_meta = "0.1"
|
|||||||
rkyv_typename = "0.7"
|
rkyv_typename = "0.7"
|
||||||
rkyv_dyn = "0.7"
|
rkyv_dyn = "0.7"
|
||||||
inventory = "0.1"
|
inventory = "0.1"
|
||||||
|
linkme = "0.2.10"
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
|
|
||||||
# Password hashing for internal users
|
# Password hashing for internal users
|
||||||
@ -77,7 +78,6 @@ capnp-rpc = "0.14.1"
|
|||||||
rsasl = { git = "https://github.com/dequbed/rsasl.git", branch = "main", default_features = false, features = ["unstable_custom_mechanism", "provider", "registry_static", "plain"] }
|
rsasl = { git = "https://github.com/dequbed/rsasl.git", branch = "main", default_features = false, features = ["unstable_custom_mechanism", "provider", "registry_static", "plain"] }
|
||||||
desfire = "0.2.0-alpha1"
|
desfire = "0.2.0-alpha1"
|
||||||
hex = { version = "0.4.3", features = ["serde"] }
|
hex = { version = "0.4.3", features = ["serde"] }
|
||||||
linkme = "0.2.10"
|
|
||||||
|
|
||||||
futures-signals = "0.3.22"
|
futures-signals = "0.3.22"
|
||||||
async-oneshot = "0.5"
|
async-oneshot = "0.5"
|
||||||
|
59
bffhd/capnp/config.rs
Normal file
59
bffhd/capnp/config.rs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
use std::fmt::Formatter;
|
||||||
|
use std::net::ToSocketAddrs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
use crate::config::deser_option;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
/// API Socket Configuration block.
|
||||||
|
///
|
||||||
|
/// One configuration block can result in several sockets if the given `address` resolves to more
|
||||||
|
/// than one SocketAddr. BFFH will attempt to bind to all of them.
|
||||||
|
pub struct Listen {
|
||||||
|
pub address: String,
|
||||||
|
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none", deserialize_with = "deser_option")]
|
||||||
|
pub port: Option<u16>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Listen {
|
||||||
|
pub fn to_tuple(&self) -> (&str, u16) {
|
||||||
|
(self.address.as_str(), self.port.unwrap_or(DEFAULT_PORT))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Listen {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}:{}", &self.address, self.port.unwrap_or(DEFAULT_PORT))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToSocketAddrs for Listen {
|
||||||
|
type Iter = <(String, u16) as ToSocketAddrs>::Iter;
|
||||||
|
|
||||||
|
fn to_socket_addrs(&self) -> std::io::Result<Self::Iter> {
|
||||||
|
if let Some(port) = self.port {
|
||||||
|
(self.address.as_str(), port).to_socket_addrs()
|
||||||
|
} else {
|
||||||
|
(self.address.as_str(), DEFAULT_PORT).to_socket_addrs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||||
|
pub struct TlsListen {
|
||||||
|
pub certfile: PathBuf,
|
||||||
|
pub keyfile: PathBuf,
|
||||||
|
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub ciphers: Option<String>,
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
pub tls_min_version: Option<String>,
|
||||||
|
#[serde(default = "Vec::new", skip_serializing_if = "Vec::is_empty")]
|
||||||
|
pub protocols: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// The default port in the non-assignable i.e. free-use area
|
||||||
|
pub const DEFAULT_PORT: u16 = 59661;
|
@ -1,6 +1,3 @@
|
|||||||
use crate::config::Listen;
|
|
||||||
|
|
||||||
|
|
||||||
use async_net::TcpListener;
|
use async_net::TcpListener;
|
||||||
|
|
||||||
|
|
||||||
@ -18,13 +15,12 @@ use std::io;
|
|||||||
|
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
|
|
||||||
use crate::authentication::AuthenticationHandle;
|
use crate::authentication::AuthenticationHandle;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
use crate::session::SessionManager;
|
use crate::session::SessionManager;
|
||||||
|
|
||||||
|
mod config;
|
||||||
|
pub use config::{Listen, TlsListen};
|
||||||
|
|
||||||
mod authenticationsystem;
|
mod authenticationsystem;
|
||||||
mod connection;
|
mod connection;
|
||||||
mod machine;
|
mod machine;
|
||||||
|
8
bffhd/config/dhall.rs
Normal file
8
bffhd/config/dhall.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
use crate::Config;
|
||||||
|
|
||||||
|
pub fn read_config_file(path: impl AsRef<Path>) -> Result<Config, serde_dhall::Error> {
|
||||||
|
serde_dhall::from_file(path)
|
||||||
|
.parse()
|
||||||
|
.map_err(Into::into)
|
||||||
|
}
|
@ -6,17 +6,23 @@ use serde::{Serialize, Deserialize};
|
|||||||
|
|
||||||
use std::fmt::Formatter;
|
use std::fmt::Formatter;
|
||||||
use std::net::{ToSocketAddrs};
|
use std::net::{ToSocketAddrs};
|
||||||
|
use serde_dhall::{SimpleType};
|
||||||
|
|
||||||
|
|
||||||
|
mod dhall;
|
||||||
|
pub use dhall::read_config_file as read;
|
||||||
|
|
||||||
use crate::authorization::permissions::{PrivilegesBuf};
|
use crate::authorization::permissions::{PrivilegesBuf};
|
||||||
use crate::authorization::roles::Role;
|
use crate::authorization::roles::Role;
|
||||||
|
use crate::capnp::{Listen, TlsListen};
|
||||||
|
use crate::logging::LogConfig;
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, serde_dhall::Error>;
|
pub fn load(path: impl AsRef<Path>, args: &clap::ArgMatches) -> anyhow::Result<Config> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read(path: &Path) -> Result<Config> {
|
pub struct ConfigBlock {
|
||||||
serde_dhall::from_file(path)
|
static_type: SimpleType,
|
||||||
.parse()
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
@ -78,7 +84,7 @@ pub struct Config {
|
|||||||
pub verbosity: isize,
|
pub verbosity: isize,
|
||||||
|
|
||||||
#[serde(default, skip)]
|
#[serde(default, skip)]
|
||||||
pub log_format: String,
|
pub logging: LogConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
@ -105,49 +111,6 @@ pub(crate) fn deser_option<'de, D, T>(d: D) -> std::result::Result<Option<T>, D:
|
|||||||
Ok(T::deserialize(d).ok())
|
Ok(T::deserialize(d).ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
pub struct Listen {
|
|
||||||
address: String,
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none", deserialize_with = "deser_option")]
|
|
||||||
port: Option<u16>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
|
||||||
pub struct TlsListen {
|
|
||||||
pub certfile: PathBuf,
|
|
||||||
pub keyfile: PathBuf,
|
|
||||||
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
||||||
pub ciphers: Option<String>,
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
||||||
pub tls_min_version: Option<String>,
|
|
||||||
#[serde(default = "Vec::new", skip_serializing_if = "Vec::is_empty")]
|
|
||||||
pub protocols: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Listen {
|
|
||||||
pub fn to_tuple(&self) -> (&str, u16) {
|
|
||||||
(self.address.as_str(), self.port.unwrap_or(DEFAULT_PORT))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Display for Listen {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{}:{}", &self.address, self.port.unwrap_or(DEFAULT_PORT))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToSocketAddrs for Listen {
|
|
||||||
type Iter = <(String, u16) as ToSocketAddrs>::Iter;
|
|
||||||
|
|
||||||
fn to_socket_addrs(&self) -> std::io::Result<Self::Iter> {
|
|
||||||
if let Some(port) = self.port {
|
|
||||||
(self.address.as_str(), port).to_socket_addrs()
|
|
||||||
} else {
|
|
||||||
(self.address.as_str(), DEFAULT_PORT).to_socket_addrs()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
@ -194,10 +157,7 @@ impl Default for Config {
|
|||||||
|
|
||||||
tlskeylog: None,
|
tlskeylog: None,
|
||||||
verbosity: 0,
|
verbosity: 0,
|
||||||
log_format: "Full".to_string(),
|
logging: LogConfig::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The default port in the non-assignable i.e. free-use area
|
|
||||||
pub const DEFAULT_PORT: u16 = 59661;
|
|
@ -40,7 +40,6 @@ mod session;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
use std::sync::{Arc};
|
use std::sync::{Arc};
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
@ -79,7 +78,7 @@ pub static RESOURCES: OnceCell<ResourcesHandle> = OnceCell::new();
|
|||||||
|
|
||||||
impl Diflouroborane {
|
impl Diflouroborane {
|
||||||
pub fn new(config: Config) -> anyhow::Result<Self> {
|
pub fn new(config: Config) -> anyhow::Result<Self> {
|
||||||
logging::init(&config);
|
logging::init(&config.logging);
|
||||||
tracing::info!(version=RELEASE_STRING, "Starting");
|
tracing::info!(version=RELEASE_STRING, "Starting");
|
||||||
|
|
||||||
let span = tracing::info_span!("setup");
|
let span = tracing::info_span!("setup");
|
||||||
|
@ -1,16 +1,46 @@
|
|||||||
use tracing_subscriber::{EnvFilter};
|
use tracing_subscriber::{EnvFilter};
|
||||||
use crate::Config;
|
use crate::Config;
|
||||||
|
|
||||||
pub fn init(config: &Config) {
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct LogConfig {
|
||||||
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
|
/// Log filter string in the tracing format `target[span{field=value}]=level`.
|
||||||
|
/// lvalue is optional and multiple filters can be combined with comma.
|
||||||
|
/// e.g. `warn,diflouroborane::actors=debug` will only print `WARN` and `ERROR` unless the
|
||||||
|
/// message is logged in a span below `diflouroborane::actors` (i.e. by an actor task) in
|
||||||
|
/// which case `DEBUG` and `INFO` will also be printed.
|
||||||
|
pub filter: Option<String>,
|
||||||
|
|
||||||
|
pub format: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LogConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
filter: None,
|
||||||
|
format: "full".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(config: &LogConfig) {
|
||||||
|
let filter = if let Some(ref filter) = config.filter {
|
||||||
|
EnvFilter::new(filter.as_str())
|
||||||
|
} else {
|
||||||
|
EnvFilter::from_env("BFFH_LOG")
|
||||||
|
};
|
||||||
|
|
||||||
let builder = tracing_subscriber::fmt()
|
let builder = tracing_subscriber::fmt()
|
||||||
.with_env_filter(EnvFilter::from_default_env());
|
.with_env_filter(filter);
|
||||||
let format = config.log_format.to_lowercase();
|
|
||||||
|
let format = config.format.to_lowercase();
|
||||||
match format.as_str() {
|
match format.as_str() {
|
||||||
"compact" => builder.compact().init(),
|
"compact" => builder.compact().init(),
|
||||||
"pretty" => builder.pretty().init(),
|
"pretty" => builder.pretty().init(),
|
||||||
"full" => builder.init(),
|
"full" => builder.init(),
|
||||||
_ => builder.init(),
|
_ => builder.init(),
|
||||||
}
|
}
|
||||||
|
|
||||||
tracing::info!(format = format.as_str(), "Logging initialized")
|
tracing::info!(format = format.as_str(), "Logging initialized")
|
||||||
}
|
}
|
@ -9,7 +9,10 @@ use rkyv_dyn::{DynDeserializer, DynError, DynSerializer};
|
|||||||
|
|
||||||
|
|
||||||
use crate::utils::oid::ObjectIdentifier;
|
use crate::utils::oid::ObjectIdentifier;
|
||||||
|
|
||||||
|
// Not using linkme because dynamically loaded modules
|
||||||
use inventory;
|
use inventory;
|
||||||
|
|
||||||
use rkyv::ser::{ScratchSpace, Serializer};
|
use rkyv::ser::{ScratchSpace, Serializer};
|
||||||
use serde::de::Error as SerdeError;
|
use serde::de::Error as SerdeError;
|
||||||
use serde::ser::SerializeMap;
|
use serde::ser::SerializeMap;
|
||||||
|
@ -8,6 +8,7 @@ use futures_rustls::TlsAcceptor;
|
|||||||
use rustls::{Certificate, PrivateKey, ServerConfig, SupportedCipherSuite};
|
use rustls::{Certificate, PrivateKey, ServerConfig, SupportedCipherSuite};
|
||||||
use rustls::version::{TLS12, TLS13};
|
use rustls::version::{TLS12, TLS13};
|
||||||
use tracing::{Level};
|
use tracing::{Level};
|
||||||
|
use crate::capnp::TlsListen;
|
||||||
use crate::config;
|
use crate::config;
|
||||||
|
|
||||||
use crate::keylog::KeyLogFile;
|
use crate::keylog::KeyLogFile;
|
||||||
@ -61,7 +62,7 @@ impl TlsConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_tls_acceptor(&self, config: &config::TlsListen) -> anyhow::Result<TlsAcceptor> {
|
pub fn make_tls_acceptor(&self, config: &TlsListen) -> anyhow::Result<TlsAcceptor> {
|
||||||
let span = tracing::debug_span!("tls");
|
let span = tracing::debug_span!("tls");
|
||||||
let _guard = span.enter();
|
let _guard = span.enter();
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use clap::{Arg, Command};
|
use clap::{Arg, Command, Parser};
|
||||||
use diflouroborane::{config, Diflouroborane};
|
use diflouroborane::{config, Diflouroborane};
|
||||||
|
|
||||||
|
|
||||||
@ -91,16 +91,23 @@ fn main() -> anyhow::Result<()> {
|
|||||||
// invalidate the generated TOML
|
// invalidate the generated TOML
|
||||||
let stdout = io::stdout();
|
let stdout = io::stdout();
|
||||||
let mut handle = stdout.lock();
|
let mut handle = stdout.lock();
|
||||||
handle.write_all(&encoded.as_bytes()).unwrap();
|
handle.write_all(encoded.as_bytes()).unwrap();
|
||||||
|
|
||||||
// Early return to exit.
|
// Early return to exit.
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else if matches.is_present("check config") {
|
} else if matches.is_present("check config") {
|
||||||
match config::read(&PathBuf::from_str(configpath).unwrap()) {
|
match config::read(&PathBuf::from_str(configpath).unwrap()) {
|
||||||
Ok(c) => {
|
Ok(c) => {
|
||||||
println!("{:#?}", c);
|
let formatted = format!("{:#?}", c);
|
||||||
println!("config is valid");
|
|
||||||
std::process::exit(0);
|
// Direct writing to fd 1 is faster but also prevents any print-formatting that could
|
||||||
|
// invalidate the generated TOML
|
||||||
|
let stdout = io::stdout();
|
||||||
|
let mut handle = stdout.lock();
|
||||||
|
handle.write_all(formatted.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
// Early return to exit.
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("{}", e);
|
eprintln!("{}", e);
|
||||||
@ -140,7 +147,7 @@ fn main() -> anyhow::Result<()> {
|
|||||||
if config.verbosity == 0 && matches.is_present("quiet") {
|
if config.verbosity == 0 && matches.is_present("quiet") {
|
||||||
config.verbosity = -1;
|
config.verbosity = -1;
|
||||||
}
|
}
|
||||||
config.log_format = matches.value_of("log format").unwrap_or("Full").to_string();
|
config.logging.format = matches.value_of("log format").unwrap_or("full").to_string();
|
||||||
|
|
||||||
let mut bffh = Diflouroborane::new(config)?;
|
let mut bffh = Diflouroborane::new(config)?;
|
||||||
bffh.run()?;
|
bffh.run()?;
|
||||||
|
Loading…
Reference in New Issue
Block a user