Skip to content

Commit

Permalink
Make the config prefix build time configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
mbuesch committed Aug 30, 2024
1 parent 0d96ce3 commit 5bb011b
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 19 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ Installing the server will also install the service and socket into systemd and
The server is used to receive knock packets from the client.
Upon successful knock authentication, the server will open the knocked port in its `nftables` firewall.

## Crates.io: Installing with `cargo install` from crates.io

TODO

## Arch Linux: Installing from AUR

If you use [Arch Linux](https://archlinux.org/), then you can install the client and the server from [AUR](https://aur.archlinux.org/packages/letmein).
Expand Down
1 change: 1 addition & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ check_dynlibs()
[ -f "$basedir/Cargo.toml" ] || die "basedir sanity check failed"

cd "$basedir" || die "cd basedir failed."
export LETMEIN_CONF_PREFIX="/opt/letmein"
cargo build || die "Cargo build (debug) failed."
cargo test || die "Cargo test failed."
cargo auditable build --release || die "Cargo build (release) failed."
Expand Down
53 changes: 43 additions & 10 deletions letmein-conf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,21 @@ mod ini;
use crate::ini::Ini;
use anyhow::{self as ah, format_err as err, Context as _};
use letmein_proto::{Key, ResourceId, UserId, PORT};
use std::{collections::HashMap, path::Path, time::Duration};

/// The default install prefix.
#[cfg(not(target_os = "windows"))]
pub const INSTALL_PREFIX: &str = "/opt/letmein";
#[cfg(target_os = "windows")]
pub const INSTALL_PREFIX: &str = "";
use std::{
collections::HashMap,
path::{Path, PathBuf},
time::Duration,
};

/// The default server configuration path, relative to the install prefix.
#[cfg(not(target_os = "windows"))]
pub const SERVER_CONF_PATH: &str = "/etc/letmeind.conf";
const SERVER_CONF_PATH: &str = "etc/letmeind.conf";

/// The default client configuration path, relative to the install prefix.
#[cfg(not(target_os = "windows"))]
pub const CLIENT_CONF_PATH: &str = "/etc/letmein.conf";
const CLIENT_CONF_PATH: &str = "etc/letmein.conf";
#[cfg(target_os = "windows")]
pub const CLIENT_CONF_PATH: &str = "letmein.conf";
const CLIENT_CONF_PATH: &str = "letmein.conf";

const DEFAULT_NFT_TIMEOUT: u32 = 600;

Expand Down Expand Up @@ -329,6 +327,7 @@ pub enum ConfigVariant {
#[derive(Clone, Default, Debug)]
pub struct Config {
variant: ConfigVariant,
path: Option<PathBuf>,
debug: bool,
port: u16,
seccomp: Seccomp,
Expand All @@ -352,13 +351,47 @@ impl Config {
}
}

/// Get the default configuration file path.
pub fn get_default_path(variant: ConfigVariant) -> PathBuf {
// The build-time environment variable LETMEIN_CONF_PREFIX can be
// used to give an additional prefix.
let prefix = match option_env!("LETMEIN_CONF_PREFIX") {
Some(env_prefix) => env_prefix,
None => {
#[cfg(not(target_os = "windows"))]
let prefix = "/";
#[cfg(target_os = "windows")]
let prefix = "";
prefix
}
};

let mut path = PathBuf::new();
path.push(prefix);
match variant {
ConfigVariant::Client => {
path.push(CLIENT_CONF_PATH);
}
ConfigVariant::Server => {
path.push(SERVER_CONF_PATH);
}
}
path
}

/// Get the actual path the configuration was read from.
pub fn get_path(&self) -> Option<&Path> {
self.path.as_deref()
}

/// (Re-)load a configuration from a file.
pub fn load(&mut self, path: &Path) -> ah::Result<()> {
if let Ok(ini) = Ini::new_from_file(path) {
self.load_ini(&ini)?;
} else if self.variant == ConfigVariant::Server {
return Err(err!("Failed to load configuration {path:?}"));
}
self.path = Some(path.to_path_buf());
Ok(())
}

Expand Down
7 changes: 4 additions & 3 deletions letmein/src/command/knock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
use anyhow::{self as ah, format_err as err, Context as _};
use letmein_conf::Config;
use letmein_proto::{Key, Message, Operation, ResourceId, UserId};
use std::sync::Arc;
use std::{path::Path, sync::Arc};

#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub enum AddrMode {
Expand Down Expand Up @@ -118,13 +118,14 @@ pub async fn run_knock(
knock_port: u16,
user: Option<UserId>,
) -> ah::Result<()> {
let confpath = conf.get_path().unwrap_or(Path::new(""));
let user = user.unwrap_or_else(|| conf.default_user());
let Some(key) = conf.key(user) else {
return Err(err!("No key found in letmein.conf for user {user}"));
return Err(err!("No key found in {confpath:?} for user {user}"));
};
let Some(resource) = conf.resource_id_by_port(knock_port, Some(user)) else {
return Err(err!(
"Port {knock_port} is not mapped to a resource in letmein.conf"
"Port {knock_port} is not mapped to a resource in {confpath:?}"
));
};
let server_port = server_port.unwrap_or_else(|| conf.port());
Expand Down
4 changes: 2 additions & 2 deletions letmein/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mod resolver;
use crate::command::{genkey::run_genkey, knock::run_knock};
use anyhow::{self as ah, Context as _};
use clap::{Parser, Subcommand};
use letmein_conf::{Config, ConfigVariant, CLIENT_CONF_PATH, INSTALL_PREFIX};
use letmein_conf::{Config, ConfigVariant};
use letmein_proto::UserId;
use std::{path::PathBuf, sync::Arc};

Expand All @@ -38,7 +38,7 @@ impl Opts {
if let Some(config) = &self.config {
config.clone()
} else {
format!("{INSTALL_PREFIX}{CLIENT_CONF_PATH}").into()
Config::get_default_path(ConfigVariant::Client)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions letmeind/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ mod server;
use crate::{protocol::Protocol, server::Server};
use anyhow::{self as ah, format_err as err, Context as _};
use clap::Parser;
use letmein_conf::{Config, ConfigVariant, Seccomp, INSTALL_PREFIX, SERVER_CONF_PATH};
use letmein_conf::{Config, ConfigVariant, Seccomp};
use letmein_seccomp::{seccomp_supported, Filter as SeccompFilter};
use std::{
fs::{create_dir_all, metadata, OpenOptions},
Expand Down Expand Up @@ -130,7 +130,7 @@ impl Opts {
if let Some(config) = &self.config {
config.clone()
} else {
format!("{INSTALL_PREFIX}{SERVER_CONF_PATH}").into()
Config::get_default_path(ConfigVariant::Server)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions letmeinfwd/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::{
};
use anyhow::{self as ah, format_err as err, Context as _};
use clap::Parser;
use letmein_conf::{Config, ConfigVariant, INSTALL_PREFIX, SERVER_CONF_PATH};
use letmein_conf::{Config, ConfigVariant};
use std::{
fs::{create_dir_all, metadata, set_permissions, OpenOptions},
io::Write as _,
Expand Down Expand Up @@ -155,7 +155,7 @@ impl Opts {
if let Some(config) = &self.config {
config.clone()
} else {
format!("{INSTALL_PREFIX}{SERVER_CONF_PATH}").into()
Config::get_default_path(ConfigVariant::Server)
}
}
}
Expand Down

0 comments on commit 5bb011b

Please sign in to comment.