fmt
This commit is contained in:
10
rustfmt.toml
Normal file
10
rustfmt.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
max_width = 120
|
||||
hard_tabs = false
|
||||
tab_spaces = 4
|
||||
edition = "2021"
|
||||
reorder_imports = true
|
||||
reorder_modules = true
|
||||
format_strings = true
|
||||
normalize_comments = true
|
||||
wrap_comments = true
|
||||
comment_width = 80
|
||||
@@ -80,11 +80,7 @@ mod tests {
|
||||
fn parses_double_quoted_argument() {
|
||||
assert_eq!(
|
||||
split_command_line(r#"/cmd arg1 "arg2 value""#),
|
||||
vec![
|
||||
"/cmd".to_string(),
|
||||
"arg1".to_string(),
|
||||
"arg2 value".to_string()
|
||||
]
|
||||
vec!["/cmd".to_string(), "arg1".to_string(), "arg2 value".to_string()]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,10 +41,7 @@ pub async fn global_usage(ctx: Arc<Mutex<BotContext>>) -> String {
|
||||
|
||||
usage += "\nCommands from plugins:\n";
|
||||
for cmd in ctx_lock.plugin_commands.values() {
|
||||
usage += &format!(
|
||||
"{} (from {}) - {}\n",
|
||||
&cmd.usage, &cmd.plugin_id, &cmd.description
|
||||
);
|
||||
usage += &format!("{} (from {}) - {}\n", &cmd.usage, &cmd.plugin_id, &cmd.description);
|
||||
}
|
||||
|
||||
usage += "\nDeltaChat Remote Control Bot by slavasil, 2026\n";
|
||||
@@ -65,12 +62,7 @@ pub async fn auth_command(
|
||||
let dchat_ctx_lock = dchat_ctx.lock().await;
|
||||
|
||||
if !AUTH_REQUIRED {
|
||||
chat::send_text_msg(
|
||||
&dchat_ctx_lock,
|
||||
chat_id,
|
||||
"Authentication is disabled".to_owned(),
|
||||
)
|
||||
.await?;
|
||||
chat::send_text_msg(&dchat_ctx_lock, chat_id, "Authentication is disabled".to_owned()).await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -80,23 +72,13 @@ pub async fn auth_command(
|
||||
}
|
||||
|
||||
let Some(password) = args.first() else {
|
||||
chat::send_text_msg(
|
||||
&dchat_ctx_lock,
|
||||
chat_id,
|
||||
"Usage: /auth <password>".to_owned(),
|
||||
)
|
||||
.await?;
|
||||
chat::send_text_msg(&dchat_ctx_lock, chat_id, "Usage: /auth <password>".to_owned()).await?;
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
if *password == ctx_lock.config.auth.password {
|
||||
ctx_lock.authed_contacts.insert(contact_id);
|
||||
chat::send_text_msg(
|
||||
&dchat_ctx_lock,
|
||||
chat_id,
|
||||
"Authentication successful!".to_owned(),
|
||||
)
|
||||
.await?;
|
||||
chat::send_text_msg(&dchat_ctx_lock, chat_id, "Authentication successful!".to_owned()).await?;
|
||||
} else {
|
||||
chat::send_text_msg(&dchat_ctx_lock, chat_id, "Incorrect password".to_owned()).await?;
|
||||
}
|
||||
@@ -201,12 +183,7 @@ async fn send_magic_packet(mac: MacAddress) -> AnyhowResult<()> {
|
||||
|
||||
fn ssh_unlock_disk_usage(config: &BotConfig) -> String {
|
||||
if !config.machines.is_empty() {
|
||||
let list = config
|
||||
.machines
|
||||
.keys()
|
||||
.cloned()
|
||||
.collect::<Vec<_>>()
|
||||
.join("|");
|
||||
let list = config.machines.keys().cloned().collect::<Vec<_>>().join("|");
|
||||
if config.default_machine().is_some() {
|
||||
format!("Usage: /ssh-unlock-disk [{list}] <password>")
|
||||
} else {
|
||||
@@ -235,12 +212,7 @@ pub async fn ssh_unlock_disk_command(
|
||||
|
||||
if args.is_empty() || args.len() > 2 {
|
||||
log::warn!("wrong number of args");
|
||||
chat::send_text_msg(
|
||||
&dchat_ctx_lock,
|
||||
chat_id,
|
||||
ssh_unlock_disk_usage(&ctx_lock.config),
|
||||
)
|
||||
.await?;
|
||||
chat::send_text_msg(&dchat_ctx_lock, chat_id, ssh_unlock_disk_usage(&ctx_lock.config)).await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -255,12 +227,7 @@ pub async fn ssh_unlock_disk_command(
|
||||
None
|
||||
}
|
||||
}) else {
|
||||
chat::send_text_msg(
|
||||
&dchat_ctx_lock,
|
||||
chat_id,
|
||||
ssh_unlock_disk_usage(&ctx_lock.config),
|
||||
)
|
||||
.await?;
|
||||
chat::send_text_msg(&dchat_ctx_lock, chat_id, ssh_unlock_disk_usage(&ctx_lock.config)).await?;
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
@@ -284,8 +251,7 @@ pub async fn ssh_unlock_disk_command(
|
||||
|
||||
let password = args[args.len() - 1].to_owned();
|
||||
let host = machine.static_ip.to_string();
|
||||
let ssh_key =
|
||||
russh::keys::PrivateKey::from_openssh(ssh_key).context("Invalid remote unlock SSH key")?;
|
||||
let ssh_key = russh::keys::PrivateKey::from_openssh(ssh_key).context("Invalid remote unlock SSH key")?;
|
||||
|
||||
drop(ctx_lock);
|
||||
drop(dchat_ctx_lock);
|
||||
@@ -311,10 +277,7 @@ pub async fn ssh_unlock_disk_command(
|
||||
SSH_TIMEOUT,
|
||||
connection.authenticate_publickey(
|
||||
"root",
|
||||
PrivateKeyWithHashAlg::new(
|
||||
Arc::new(ssh_key),
|
||||
connection.best_supported_rsa_hash().await?.flatten(),
|
||||
),
|
||||
PrivateKeyWithHashAlg::new(Arc::new(ssh_key), connection.best_supported_rsa_hash().await?.flatten()),
|
||||
),
|
||||
)
|
||||
.await
|
||||
@@ -350,10 +313,7 @@ pub async fn ssh_unlock_disk_command(
|
||||
.context("Cannot send password via SSH")?;
|
||||
|
||||
loop {
|
||||
let Some(msg) = timeout(SSH_TIMEOUT, channel.wait())
|
||||
.await
|
||||
.context("Timed out")?
|
||||
else {
|
||||
let Some(msg) = timeout(SSH_TIMEOUT, channel.wait()).await.context("Timed out")? else {
|
||||
break;
|
||||
};
|
||||
log::info!("Received message from SSH server: {:?}", msg);
|
||||
@@ -372,12 +332,7 @@ pub async fn ssh_unlock_disk_command(
|
||||
|
||||
fn ssh_exec_usage(config: &BotConfig) -> String {
|
||||
if !config.machines.is_empty() {
|
||||
let list = config
|
||||
.machines
|
||||
.keys()
|
||||
.cloned()
|
||||
.collect::<Vec<_>>()
|
||||
.join("|");
|
||||
let list = config.machines.keys().cloned().collect::<Vec<_>>().join("|");
|
||||
format!("Usage: /ssh-exec <username>@({list}|<hostname>|<IP address>) <command...>")
|
||||
} else {
|
||||
"Command /ssh-exec unavailable: no machines configured".to_string()
|
||||
@@ -499,24 +454,16 @@ pub async fn ssh_exec_command(
|
||||
russh::ChannelMsg::Data { data } => {
|
||||
let dchat_ctx_lock = dchat_ctx.lock().await;
|
||||
report_text += &String::from_utf8_lossy(&data);
|
||||
chat::send_edit_request(
|
||||
&dchat_ctx_lock,
|
||||
report_message_id,
|
||||
report_text.clone(),
|
||||
)
|
||||
.await
|
||||
.context("Cannot edit message")?;
|
||||
chat::send_edit_request(&dchat_ctx_lock, report_message_id, report_text.clone())
|
||||
.await
|
||||
.context("Cannot edit message")?;
|
||||
}
|
||||
russh::ChannelMsg::ExtendedData { data, ext: 1 } => {
|
||||
let dchat_ctx_lock = dchat_ctx.lock().await;
|
||||
report_text += &String::from_utf8_lossy(&data);
|
||||
chat::send_edit_request(
|
||||
&dchat_ctx_lock,
|
||||
report_message_id,
|
||||
report_text.clone(),
|
||||
)
|
||||
.await
|
||||
.context("Cannot edit message")?;
|
||||
chat::send_edit_request(&dchat_ctx_lock, report_message_id, report_text.clone())
|
||||
.await
|
||||
.context("Cannot edit message")?;
|
||||
}
|
||||
_ => {
|
||||
log::info!("Message from SSH channel: {msg:?}");
|
||||
@@ -531,13 +478,9 @@ pub async fn ssh_exec_command(
|
||||
|
||||
let dchat_ctx_lock = dchat_ctx.lock().await;
|
||||
report_text += "\n\nRead timed out";
|
||||
chat::send_edit_request(
|
||||
&dchat_ctx_lock,
|
||||
report_message_id,
|
||||
report_text.clone(),
|
||||
)
|
||||
.await
|
||||
.context("Cannot edit message")?;
|
||||
chat::send_edit_request(&dchat_ctx_lock, report_message_id, report_text.clone())
|
||||
.await
|
||||
.context("Cannot edit message")?;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
104
src/main.rs
104
src/main.rs
@@ -7,10 +7,7 @@ mod ssh;
|
||||
mod proto {
|
||||
pub(crate) mod deltachat_remotecontrol_bot {
|
||||
pub(crate) mod plugin {
|
||||
include!(concat!(
|
||||
env!("OUT_DIR"),
|
||||
"/deltachat_remotecontrol_bot.plugin.rs"
|
||||
));
|
||||
include!(concat!(env!("OUT_DIR"), "/deltachat_remotecontrol_bot.plugin.rs"));
|
||||
}
|
||||
}
|
||||
pub(crate) use deltachat_remotecontrol_bot::plugin::*;
|
||||
@@ -82,14 +79,9 @@ async fn run_bot(bot_context: Arc<Mutex<BotContext>>) -> AnyhowResult<()> {
|
||||
|
||||
let dchat_db_filename = dchat_db_dir.join("deltachat.sqlite");
|
||||
|
||||
let dchat_ctx = Context::new(
|
||||
&dchat_db_filename,
|
||||
0,
|
||||
Events::default(),
|
||||
StockStrings::default(),
|
||||
)
|
||||
.await
|
||||
.context("Failed to open Delta Chat client DB")?;
|
||||
let dchat_ctx = Context::new(&dchat_db_filename, 0, Events::default(), StockStrings::default())
|
||||
.await
|
||||
.context("Failed to open Delta Chat client DB")?;
|
||||
|
||||
let ctx_lock = bot_context.lock().await;
|
||||
|
||||
@@ -114,9 +106,7 @@ async fn run_bot(bot_context: Arc<Mutex<BotContext>>) -> AnyhowResult<()> {
|
||||
avatar_path = data_path().join(&avatar_path);
|
||||
}
|
||||
if let Some(avatar_str) = avatar_path.to_str() {
|
||||
dchat_ctx
|
||||
.set_config(Config::Selfavatar, Some(avatar_str))
|
||||
.await?;
|
||||
dchat_ctx.set_config(Config::Selfavatar, Some(avatar_str)).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,12 +146,7 @@ async fn send_command_not_found(
|
||||
chat_id: ChatId,
|
||||
) -> AnyhowResult<()> {
|
||||
let dchat_ctx_lock = dchat_ctx.lock().await;
|
||||
chat::send_text_msg(
|
||||
&dchat_ctx_lock,
|
||||
chat_id,
|
||||
commands::global_usage(bot_ctx).await,
|
||||
)
|
||||
.await?;
|
||||
chat::send_text_msg(&dchat_ctx_lock, chat_id, commands::global_usage(bot_ctx).await).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -208,9 +193,7 @@ async fn handle_message(
|
||||
};
|
||||
|
||||
let Some(plugin) = ctx_lock.plugins.get(&cmd.plugin_id) else {
|
||||
bail!(
|
||||
"Inconsistency in plugin_cmd_aliases hashmap: command references a plugin that is not loaded"
|
||||
);
|
||||
bail!("Inconsistency in plugin_cmd_aliases hashmap: command references a plugin that is not loaded");
|
||||
};
|
||||
let (plugin_conn, plugin_name) = {
|
||||
let lock = plugin.lock().await;
|
||||
@@ -218,11 +201,7 @@ async fn handle_message(
|
||||
bail!("Plugin disconnected");
|
||||
};
|
||||
let plugin_name = lock.plugin_id.clone();
|
||||
log::info!(
|
||||
"Delegating command /{} to plugin {}",
|
||||
&cmd.name,
|
||||
&plugin_name
|
||||
);
|
||||
log::info!("Delegating command /{} to plugin {}", &cmd.name, &plugin_name);
|
||||
(conn, plugin_name)
|
||||
};
|
||||
let contact_id = msg.get_from_id();
|
||||
@@ -239,11 +218,7 @@ async fn handle_message(
|
||||
tokio::spawn(async move {
|
||||
log::debug!("Started plugin command task");
|
||||
match plugin_conn
|
||||
.execute_command(
|
||||
cmd_name.clone(),
|
||||
issuer_id,
|
||||
commands::args::split_command_line(&text),
|
||||
)
|
||||
.execute_command(cmd_name.clone(), issuer_id, commands::args::split_command_line(&text))
|
||||
.await
|
||||
{
|
||||
Ok(mut replies) => {
|
||||
@@ -259,21 +234,15 @@ async fn handle_message(
|
||||
);
|
||||
if reply.edit {
|
||||
if let Some(msg_id) = last_message_id {
|
||||
if let Some(proto::command_reply::Reply::Text(text)) =
|
||||
reply.reply
|
||||
{
|
||||
if let Some(proto::command_reply::Reply::Text(text)) = reply.reply {
|
||||
let dchat_ctx_lock = dchat_ctx.lock().await;
|
||||
log::debug!(
|
||||
"Command {} :: /{}: editing last message",
|
||||
&plugin_name,
|
||||
&cmd_name
|
||||
);
|
||||
if let Err(e) = chat::send_edit_request(
|
||||
&dchat_ctx_lock,
|
||||
msg_id,
|
||||
text,
|
||||
)
|
||||
.await
|
||||
if let Err(e) =
|
||||
chat::send_edit_request(&dchat_ctx_lock, msg_id, text).await
|
||||
{
|
||||
log::error!("Cannot edit message: {e}");
|
||||
continue;
|
||||
@@ -285,40 +254,22 @@ async fn handle_message(
|
||||
&plugin_name
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if let Some(proto::command_reply::Reply::Text(text)) =
|
||||
reply.reply
|
||||
} else if let Some(proto::command_reply::Reply::Text(text)) = reply.reply {
|
||||
let dchat_ctx_lock = dchat_ctx.lock().await;
|
||||
log::debug!("Command {} :: /{}: sending message", &plugin_name, &cmd_name);
|
||||
let msg_id = match chat::send_text_msg(&dchat_ctx_lock, chat_id, text).await
|
||||
{
|
||||
let dchat_ctx_lock = dchat_ctx.lock().await;
|
||||
log::debug!(
|
||||
"Command {} :: /{}: sending message",
|
||||
&plugin_name,
|
||||
&cmd_name
|
||||
);
|
||||
let msg_id = match chat::send_text_msg(
|
||||
&dchat_ctx_lock,
|
||||
chat_id,
|
||||
text,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(msg_id) => msg_id,
|
||||
Err(e) => {
|
||||
log::error!("Cannot send new message: {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
last_message_id = Some(msg_id);
|
||||
}
|
||||
Ok(msg_id) => msg_id,
|
||||
Err(e) => {
|
||||
log::error!("Cannot send new message: {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
last_message_id = Some(msg_id);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!(
|
||||
"Error while executing {} :: /{}: {}",
|
||||
&plugin_name,
|
||||
&cmd_name,
|
||||
e
|
||||
);
|
||||
log::error!("Error while executing {} :: /{}: {}", &plugin_name, &cmd_name, e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -374,12 +325,7 @@ async fn main() {
|
||||
}
|
||||
};
|
||||
|
||||
let requested_plugins: Vec<PluginConfig> = config
|
||||
.plugins
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter(|p| p.enabled)
|
||||
.collect();
|
||||
let requested_plugins: Vec<PluginConfig> = config.plugins.clone().into_iter().filter(|p| p.enabled).collect();
|
||||
|
||||
let bot_context = Arc::new(Mutex::new(BotContext::new(config)));
|
||||
|
||||
|
||||
15
src/paths.rs
15
src/paths.rs
@@ -16,11 +16,7 @@ pub(crate) fn default_config_paths() -> Vec<PathBuf> {
|
||||
paths.push(config_home.join(APP_CONFIG_DIR).join(CONFIG_FILENAME));
|
||||
}
|
||||
|
||||
paths.push(
|
||||
PathBuf::from("/etc")
|
||||
.join(APP_CONFIG_DIR)
|
||||
.join(CONFIG_FILENAME),
|
||||
);
|
||||
paths.push(PathBuf::from("/etc").join(APP_CONFIG_DIR).join(CONFIG_FILENAME));
|
||||
|
||||
paths
|
||||
}
|
||||
@@ -28,14 +24,7 @@ pub(crate) fn default_config_paths() -> Vec<PathBuf> {
|
||||
pub(crate) fn data_path() -> PathBuf {
|
||||
std::env::var("XDG_DATA_HOME")
|
||||
.map(|dh| PathBuf::from(dh).join(APP_DATA_DIR))
|
||||
.or_else(|_| {
|
||||
std::env::var("HOME").map(|h| {
|
||||
PathBuf::from(h)
|
||||
.join(".local")
|
||||
.join("share")
|
||||
.join(APP_DATA_DIR)
|
||||
})
|
||||
})
|
||||
.or_else(|_| std::env::var("HOME").map(|h| PathBuf::from(h).join(".local").join("share").join(APP_DATA_DIR)))
|
||||
.unwrap_or(PathBuf::from("."))
|
||||
}
|
||||
|
||||
|
||||
@@ -58,24 +58,17 @@ impl Display for PluginRequestType {
|
||||
|
||||
#[async_trait]
|
||||
pub(crate) trait PluginConnection: Send + Sync + Debug {
|
||||
async fn initialize_plugin(
|
||||
&self,
|
||||
config: String,
|
||||
) -> Result<proto::PluginInitializeResponse, PluginConnectionError>;
|
||||
async fn initialize_plugin(&self, config: String)
|
||||
-> Result<proto::PluginInitializeResponse, PluginConnectionError>;
|
||||
|
||||
async fn request_plugin_command_list(
|
||||
&self,
|
||||
) -> Result<proto::PluginCommandListResponse, PluginConnectionError>;
|
||||
async fn request_plugin_command_list(&self) -> Result<proto::PluginCommandListResponse, PluginConnectionError>;
|
||||
|
||||
async fn execute_command(
|
||||
self: Arc<Self>,
|
||||
command_id: String,
|
||||
issuer_id: String,
|
||||
argv: Vec<String>,
|
||||
) -> Result<
|
||||
mpsc::Receiver<Result<proto::CommandReply, PluginConnectionError>>,
|
||||
PluginConnectionError,
|
||||
>;
|
||||
) -> Result<mpsc::Receiver<Result<proto::CommandReply, PluginConnectionError>>, PluginConnectionError>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -138,8 +131,7 @@ pub(crate) async fn try_load_plugin(
|
||||
cmd.env("DCRCBOT_PLUGIN_TRANSPORT", "stdio");
|
||||
|
||||
let plugin_process = cmd.spawn().context("Failed to start the plugin")?;
|
||||
let plugin =
|
||||
stdio::initialize_stdio_plugin(plugin_process, unique_name.clone(), config_json).await?;
|
||||
let plugin = stdio::initialize_stdio_plugin(plugin_process, unique_name.clone(), config_json).await?;
|
||||
|
||||
let mut ctx_lock = ctx.lock().await;
|
||||
for cmd in plugin.lock().await.commands.iter().cloned() {
|
||||
@@ -147,12 +139,8 @@ pub(crate) async fn try_load_plugin(
|
||||
if ctx_lock.plugin_commands.contains_key(&cmd.name) {
|
||||
bail!("duplicate command specification");
|
||||
}
|
||||
ctx_lock
|
||||
.plugin_commands
|
||||
.insert(cmd.name.clone(), Arc::clone(&cmd));
|
||||
ctx_lock
|
||||
.plugin_cmd_aliases
|
||||
.insert(cmd.name.clone(), Arc::clone(&cmd));
|
||||
ctx_lock.plugin_commands.insert(cmd.name.clone(), Arc::clone(&cmd));
|
||||
ctx_lock.plugin_cmd_aliases.insert(cmd.name.clone(), Arc::clone(&cmd));
|
||||
for alias in cmd.aliases.iter() {
|
||||
log::debug!(
|
||||
"adding command alias /{} -> /{} of plugin {}",
|
||||
@@ -160,9 +148,7 @@ pub(crate) async fn try_load_plugin(
|
||||
&cmd.name,
|
||||
&unique_name
|
||||
);
|
||||
ctx_lock
|
||||
.plugin_cmd_aliases
|
||||
.insert(alias.to_owned(), Arc::clone(&cmd));
|
||||
ctx_lock.plugin_cmd_aliases.insert(alias.to_owned(), Arc::clone(&cmd));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,7 @@ use tokio::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
plugin::{
|
||||
LoadedPlugin, PluginCommand, PluginConnection, PluginConnectionError, PluginRequestType,
|
||||
},
|
||||
plugin::{LoadedPlugin, PluginCommand, PluginConnection, PluginConnectionError, PluginRequestType},
|
||||
proto,
|
||||
};
|
||||
|
||||
@@ -85,19 +83,16 @@ impl StdioPluginConnection {
|
||||
|
||||
async fn stdout_reader_loop(self: Arc<Self>) {
|
||||
loop {
|
||||
let frame =
|
||||
match Self::read_length_delimited(self.buffered_stdout.lock().await.deref_mut())
|
||||
.await
|
||||
{
|
||||
Ok(frame) => frame,
|
||||
Err(e) => {
|
||||
log::error!(
|
||||
"Error while reading STDOUT of stdio plugin {}: {e}",
|
||||
&self.plugin.lock().await.plugin_id
|
||||
);
|
||||
break;
|
||||
}
|
||||
};
|
||||
let frame = match Self::read_length_delimited(self.buffered_stdout.lock().await.deref_mut()).await {
|
||||
Ok(frame) => frame,
|
||||
Err(e) => {
|
||||
log::error!(
|
||||
"Error while reading STDOUT of stdio plugin {}: {e}",
|
||||
&self.plugin.lock().await.plugin_id
|
||||
);
|
||||
break;
|
||||
}
|
||||
};
|
||||
let response = match proto::Response::decode(frame.as_slice()) {
|
||||
Ok(response) => response,
|
||||
Err(_) => {
|
||||
@@ -133,9 +128,7 @@ impl StdioPluginConnection {
|
||||
self.pending_requests.lock().await.clear();
|
||||
}
|
||||
|
||||
async fn read_length_delimited<R>(
|
||||
reader: &mut R,
|
||||
) -> Result<Vec<u8>, Box<dyn Error + Send + Sync>>
|
||||
async fn read_length_delimited<R>(reader: &mut R) -> Result<Vec<u8>, Box<dyn Error + Send + Sync>>
|
||||
where
|
||||
R: AsyncRead + Unpin,
|
||||
{
|
||||
|
||||
23
src/ssh.rs
23
src/ssh.rs
@@ -36,11 +36,7 @@ pub(crate) async fn connect_ssh<A: ToSocketAddrs + Debug, K: AsRef<[u8]>, P: Int
|
||||
"Connecting to SSH {:?} {} key & {} password",
|
||||
&addr,
|
||||
if key.is_some() { "with" } else { "without" },
|
||||
if password.is_some() {
|
||||
"with"
|
||||
} else {
|
||||
"without"
|
||||
}
|
||||
if password.is_some() { "with" } else { "without" }
|
||||
);
|
||||
let mut connection = tokio::time::timeout(
|
||||
connect_timeout,
|
||||
@@ -65,12 +61,7 @@ pub(crate) async fn connect_ssh<A: ToSocketAddrs + Debug, K: AsRef<[u8]>, P: Int
|
||||
if !auth_success {
|
||||
if let Some(key) = key {
|
||||
log::info!("Trying to authenticate using key");
|
||||
match tokio::time::timeout(
|
||||
auth_timeout,
|
||||
connection.authenticate_publickey(username, key),
|
||||
)
|
||||
.await
|
||||
{
|
||||
match tokio::time::timeout(auth_timeout, connection.authenticate_publickey(username, key)).await {
|
||||
Ok(Ok(AuthResult::Success)) => {
|
||||
auth_success = true;
|
||||
}
|
||||
@@ -78,8 +69,7 @@ pub(crate) async fn connect_ssh<A: ToSocketAddrs + Debug, K: AsRef<[u8]>, P: Int
|
||||
remaining_methods,
|
||||
partial_success,
|
||||
})) => {
|
||||
if partial_success || !remaining_methods.contains(&russh::MethodKind::Password)
|
||||
{
|
||||
if partial_success || !remaining_methods.contains(&russh::MethodKind::Password) {
|
||||
if partial_success {
|
||||
anyhow::bail!("SSH auth failed: multi-factor auth is not supported");
|
||||
} else {
|
||||
@@ -102,12 +92,7 @@ pub(crate) async fn connect_ssh<A: ToSocketAddrs + Debug, K: AsRef<[u8]>, P: Int
|
||||
if !auth_success {
|
||||
if let Some(password) = password {
|
||||
log::info!("Trying to authenticate using password");
|
||||
match tokio::time::timeout(
|
||||
auth_timeout,
|
||||
connection.authenticate_password(username, password),
|
||||
)
|
||||
.await
|
||||
{
|
||||
match tokio::time::timeout(auth_timeout, connection.authenticate_password(username, password)).await {
|
||||
Ok(Ok(AuthResult::Success)) => {
|
||||
auth_success = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user