Skip to content

Commit

Permalink
Add password_command config option
Browse files Browse the repository at this point in the history
closes #424
  • Loading branch information
4e554c4c committed Sep 16, 2024
1 parent 2b46a9d commit 1523e5b
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 6 deletions.
8 changes: 8 additions & 0 deletions book/src/configuration/servers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ Read password from the file at the given path.[^1]
- **values**: any string
- **default**: not set

## `password_command`

Executes the command with `sh` (or equivalent) and reads `password` as the output.

- **type**: string
- **values**: any string
- **default**: not set

## `channels`

A list of channels to join on connection.
Expand Down
10 changes: 9 additions & 1 deletion book/src/configuration/servers/sasl/plain.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,12 @@ Read `password` from the file at the given path.[^1]
- **values**: any string
- **default**: not set

[^1]: Shell expansions (e.g. `"~/"``"/home/user/"`) are not supported in path strings.
## `password_command`

Executes the command with `sh` (or equivalent) and reads `password` as the output.

- **type**: string
- **values**: any string
- **default**: not set

[^1]: Shell expansions (e.g. `"~/"``"/home/user/"`) are not supported in path strings.
5 changes: 4 additions & 1 deletion data/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::path::PathBuf;
use std::string;

use tokio::fs;
use tokio_stream::StreamExt;
Expand Down Expand Up @@ -173,7 +174,7 @@ impl Config {
tooltips,
} = toml::from_str(content.as_ref()).map_err(|e| Error::Parse(e.to_string()))?;

servers.read_password_files().await?;
servers.read_passwords().await?;

let loaded_notifications = notifications.load_sounds()?;

Expand Down Expand Up @@ -304,6 +305,8 @@ pub enum Error {
Io(String),
#[error("{0}")]
Parse(String),
#[error("UTF8 parsing error: {0}")]
UI(#[from] string::FromUtf8Error),
#[error(transparent)]
LoadSounds(#[from] audio::LoadError),
}
Expand Down
3 changes: 3 additions & 0 deletions data/src/config/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ pub struct Server {
pub password: Option<String>,
/// The file with the password to connect to the server.
pub password_file: Option<String>,
/// The command which outputs a password to connect to the server.
pub password_command: Option<String>,
/// A list of channels to join on connection.
#[serde(default)]
pub channels: Vec<String>,
Expand Down Expand Up @@ -149,6 +151,7 @@ impl Default for Server {
port: default_tls_port(),
password: Default::default(),
password_file: Default::default(),
password_command: Default::default(),
channels: Default::default(),
channel_keys: Default::default(),
ping_time: default_ping_time(),
Expand Down
30 changes: 26 additions & 4 deletions data/src/server.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::BTreeMap;
use std::fmt;

use tokio::fs;
use tokio::process::Command;

use futures::channel::mpsc::Sender;
use irc::proto;
Expand Down Expand Up @@ -73,17 +73,39 @@ impl Map {
self.0.iter().map(Entry::from)
}

pub async fn read_password_files(&mut self) -> Result<(), Error> {
pub async fn read_passwords(&mut self) -> Result<(), Error> {
for (_, config) in self.0.iter_mut() {
if let Some(pass_file) = &config.password_file {
if config.password.is_some() {
if config.password.is_some() || config.password_command.is_some() {
return Err(Error::Parse(
"Only one of password and password_file can be set.".to_string(),
"Only one of password, password_file and password_command can be set.".to_string(),
));
}
let pass = fs::read_to_string(pass_file).await?;
config.password = Some(pass);
}
if let Some(pass_command) = &config.password_command {
if config.password.is_some() {
return Err(Error::Parse(
"Only one of password, password_file and password_command can be set.".to_string(),
));
}
let output = if cfg!(target_os = "windows") {
Command::new("cmd")
.args(["/C", pass_command])
.output()
.await
.expect("failed to execute process")
} else {
Command::new("sh")
.arg("-c")
.arg(pass_command)
.output()
.await
.expect("failed to execute process")
};
config.password = Some(String::from_utf8(output.stdout)?);
}
if let Some(nick_pass_file) = &config.nick_password_file {
if config.nick_password.is_some() {
return Err(Error::Parse(
Expand Down

0 comments on commit 1523e5b

Please sign in to comment.