Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support gating libssh-rs and ssh2 behind features of same name #1415

Merged
merged 2 commits into from
Jan 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions wezterm-ssh/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ documentation = "https://docs.rs/wezterm-ssh"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
default = ["libssh-rs", "ssh2"]
vendored-openssl = ["ssh2/vendored-openssl", "libssh-rs/vendored-openssl"]
vendored-openssl-ssh2 = ["ssh2/vendored-openssl"]
vendored-openssl-libssh-rs = ["libssh-rs/vendored-openssl"]

[dependencies]
anyhow = "1.0"
Expand All @@ -26,9 +29,9 @@ log = "0.4"
portable-pty = { version="0.7", path = "../pty" }
regex = "1"
smol = "1.2"
ssh2 = {version="0.9.3", features=["openssl-on-win32"]}
libssh-rs = {version="0.1.2", features=["vendored"], git="https://github.com/wez/libssh-rs.git"}
#libssh-rs = {path="../../libssh-rs/libssh-rs", features=["vendored"]}
ssh2 = {version="0.9.3", features=["openssl-on-win32"], optional = true}
libssh-rs = {version="0.1.2", features=["vendored"], git="https://github.com/wez/libssh-rs.git", optional = true}
#libssh-rs = {path="../../libssh-rs/libssh-rs", features=["vendored"], optional = true}
thiserror = "1.0"

# Not used directly, but is used to centralize the openssl vendor feature selection
Expand Down
16 changes: 11 additions & 5 deletions wezterm-ssh/src/auth.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use crate::session::SessionEvent;
use anyhow::Context;
use libssh_rs as libssh;
use smol::channel::{bounded, Sender};
use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};

#[derive(Debug)]
pub struct AuthenticationPrompt {
Expand All @@ -30,6 +27,7 @@ impl AuthenticationEvent {
}

impl crate::sessioninner::SessionInner {
#[cfg(feature = "ssh2")]
fn agent_auth(&mut self, sess: &ssh2::Session, user: &str) -> anyhow::Result<bool> {
if let Some(only) = self.config.get("identitiesonly") {
if only == "yes" {
Expand All @@ -55,12 +53,15 @@ impl crate::sessioninner::SessionInner {
Ok(false)
}

#[cfg(feature = "ssh2")]
fn pubkey_auth(
&mut self,
sess: &ssh2::Session,
user: &str,
host: &str,
) -> anyhow::Result<bool> {
use std::path::{Path, PathBuf};

if let Some(files) = self.config.get("identityfile") {
for file in files.split_whitespace() {
let pubkey: PathBuf = format!("{}.pub", file).into();
Expand Down Expand Up @@ -127,7 +128,9 @@ impl crate::sessioninner::SessionInner {
Ok(false)
}

pub fn authenticate_libssh(&mut self, sess: &libssh::Session) -> anyhow::Result<()> {
#[cfg(feature = "libssh-rs")]
pub fn authenticate_libssh(&mut self, sess: &libssh_rs::Session) -> anyhow::Result<()> {
use std::collections::HashMap;
let tx = self.tx_event.clone();

// Set the callback for pubkey auth
Expand All @@ -153,7 +156,7 @@ impl crate::sessioninner::SessionInner {
Ok(answers.remove(0))
});

use libssh::{AuthMethods, AuthStatus};
use libssh_rs::{AuthMethods, AuthStatus};
match sess.userauth_none(None)? {
AuthStatus::Success => return Ok(()),
_ => {}
Expand Down Expand Up @@ -249,12 +252,15 @@ impl crate::sessioninner::SessionInner {
}
}

#[cfg(feature = "ssh2")]
pub fn authenticate(
&mut self,
sess: &ssh2::Session,
user: &str,
host: &str,
) -> anyhow::Result<()> {
use std::collections::HashSet;

loop {
if sess.authenticated() {
return Ok(());
Expand Down
42 changes: 39 additions & 3 deletions wezterm-ssh/src/channelwrap.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use crate::pty::{NewPty, ResizePty};
use libssh_rs as libssh;
use portable_pty::ExitStatus;

pub(crate) enum ChannelWrap {
#[cfg(feature = "ssh2")]
Ssh2(ssh2::Channel),
LibSsh(libssh::Channel),

#[cfg(feature = "libssh-rs")]
LibSsh(libssh_rs::Channel),
}

#[cfg(feature = "ssh2")]
fn has_signal(chan: &ssh2::Channel) -> Option<ssh2::ExitSignal> {
if let Ok(sig) = chan.exit_signal() {
if sig.exit_signal.is_some() {
Expand All @@ -19,6 +22,7 @@ fn has_signal(chan: &ssh2::Channel) -> Option<ssh2::ExitSignal> {
impl ChannelWrap {
pub fn exit_status(&mut self) -> Option<ExitStatus> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(chan) => {
if chan.eof() && chan.wait_close().is_ok() {
if let Some(_sig) = has_signal(chan) {
Expand All @@ -32,6 +36,8 @@ impl ChannelWrap {
None
}
}

#[cfg(feature = "libssh-rs")]
Self::LibSsh(chan) => {
if chan.is_eof() {
if let Some(status) = chan.get_exit_status() {
Expand All @@ -45,7 +51,10 @@ impl ChannelWrap {

pub fn reader(&mut self, idx: usize) -> Box<dyn std::io::Read + '_> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(chan) => Box::new(chan.stream(idx as i32)),

#[cfg(feature = "libssh-rs")]
Self::LibSsh(chan) => match idx {
0 => Box::new(chan.stdout()),
1 => Box::new(chan.stderr()),
Expand All @@ -56,16 +65,22 @@ impl ChannelWrap {

pub fn writer(&mut self) -> Box<dyn std::io::Write + '_> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(chan) => Box::new(chan),

#[cfg(feature = "libssh-rs")]
Self::LibSsh(chan) => Box::new(chan.stdin()),
}
}

pub fn close(&mut self) {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(chan) => {
let _ = chan.close();
}

#[cfg(feature = "libssh-rs")]
Self::LibSsh(chan) => {
let _ = chan.close();
}
Expand All @@ -74,6 +89,7 @@ impl ChannelWrap {

pub fn request_pty(&mut self, newpty: &NewPty) -> anyhow::Result<()> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(chan) => Ok(chan.request_pty(
&newpty.term,
None,
Expand All @@ -84,6 +100,8 @@ impl ChannelWrap {
newpty.size.pixel_height.into(),
)),
)?),

#[cfg(feature = "libssh-rs")]
Self::LibSsh(chan) => Ok(chan.request_pty(
&newpty.term,
newpty.size.cols.into(),
Expand All @@ -94,42 +112,60 @@ impl ChannelWrap {

pub fn request_env(&mut self, name: &str, value: &str) -> anyhow::Result<()> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(chan) => Ok(chan.setenv(name, value)?),

#[cfg(feature = "libssh-rs")]
Self::LibSsh(chan) => Ok(chan.request_env(name, value)?),
}
}

pub fn request_exec(&mut self, command_line: &str) -> anyhow::Result<()> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(chan) => Ok(chan.exec(command_line)?),

#[cfg(feature = "libssh-rs")]
Self::LibSsh(chan) => Ok(chan.request_exec(command_line)?),
}
}

pub fn request_shell(&mut self) -> anyhow::Result<()> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(chan) => Ok(chan.shell()?),

#[cfg(feature = "libssh-rs")]
Self::LibSsh(chan) => Ok(chan.request_shell()?),
}
}

pub fn resize_pty(&mut self, resize: &ResizePty) -> anyhow::Result<()> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(chan) => Ok(chan.request_pty_size(
resize.size.cols.into(),
resize.size.rows.into(),
Some(resize.size.pixel_width.into()),
Some(resize.size.pixel_height.into()),
)?),

#[cfg(feature = "libssh-rs")]
Self::LibSsh(chan) => {
Ok(chan.change_pty_size(resize.size.cols.into(), resize.size.rows.into())?)
}
}
}

pub fn send_signal(&mut self, signame: &str) -> anyhow::Result<()> {
pub fn send_signal(
&mut self,
#[cfg_attr(not(feature = "libssh-rs"), allow(unused_variables))] signame: &str,
) -> anyhow::Result<()> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(_) => Ok(()),

#[cfg(feature = "libssh-rs")]
Self::LibSsh(chan) => Ok(chan.request_send_signal(signame)?),
}
}
Expand Down
11 changes: 8 additions & 3 deletions wezterm-ssh/src/dirwrap.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
use crate::sftp::types::Metadata;
use crate::sftp::{SftpChannelError, SftpChannelResult};
use camino::Utf8PathBuf;
use libssh_rs as libssh;
use std::convert::TryFrom;

pub(crate) enum DirWrap {
#[cfg(feature = "ssh2")]
Ssh2(ssh2::File),
LibSsh(libssh::SftpDir),

#[cfg(feature = "libssh-rs")]
LibSsh(libssh_rs::SftpDir),
}

impl DirWrap {
pub fn read_dir(&mut self) -> SftpChannelResult<(Utf8PathBuf, Metadata)> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(file) => {
use std::convert::TryFrom;
file.readdir()
.map_err(SftpChannelError::from)
.and_then(|(path, stat)| match Utf8PathBuf::try_from(path) {
Expand All @@ -23,6 +26,8 @@ impl DirWrap {
))),
})
}

#[cfg(feature = "libssh-rs")]
Self::LibSsh(dir) => match dir.read_dir() {
None => Err(SftpChannelError::from(std::io::Error::new(
std::io::ErrorKind::UnexpectedEof,
Expand Down
34 changes: 28 additions & 6 deletions wezterm-ssh/src/filewrap.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,45 @@
use crate::sftp::types::Metadata;
use crate::sftp::{SftpChannelError, SftpChannelResult};
use libssh_rs as libssh;
use std::io::Write;

pub(crate) enum FileWrap {
#[cfg(feature = "ssh2")]
Ssh2(ssh2::File),
LibSsh(libssh::SftpFile),

#[cfg(feature = "libssh-rs")]
LibSsh(libssh_rs::SftpFile),
}

impl FileWrap {
pub fn reader(&mut self) -> Box<dyn std::io::Read + '_> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(file) => Box::new(file),

#[cfg(feature = "libssh-rs")]
Self::LibSsh(file) => Box::new(file),
}
}

pub fn writer(&mut self) -> Box<dyn std::io::Write + '_> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(file) => Box::new(file),

#[cfg(feature = "libssh-rs")]
Self::LibSsh(file) => Box::new(file),
}
}

pub fn set_metadata(&mut self, metadata: Metadata) -> SftpChannelResult<()> {
pub fn set_metadata(
&mut self,
#[cfg_attr(not(feature = "ssh2"), allow(unused_variables))] metadata: Metadata,
) -> SftpChannelResult<()> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(file) => Ok(file.setstat(metadata.into())?),
Self::LibSsh(_file) => Err(libssh::Error::fatal(

#[cfg(feature = "libssh-rs")]
Self::LibSsh(_file) => Err(libssh_rs::Error::fatal(
"FileWrap::set_metadata not implemented for libssh::SftpFile",
)
.into()),
Expand All @@ -35,7 +48,10 @@ impl FileWrap {

pub fn metadata(&mut self) -> SftpChannelResult<Metadata> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(file) => Ok(file.stat().map(Metadata::from)?),

#[cfg(feature = "libssh-rs")]
Self::LibSsh(file) => file
.metadata()
.map(Metadata::from)
Expand All @@ -45,8 +61,14 @@ impl FileWrap {

pub fn fsync(&mut self) -> SftpChannelResult<()> {
match self {
#[cfg(feature = "ssh2")]
Self::Ssh2(file) => file.fsync().map_err(SftpChannelError::from),
Self::LibSsh(file) => Ok(file.flush()?),

#[cfg(feature = "libssh-rs")]
Self::LibSsh(file) => {
use std::io::Write;
Ok(file.flush()?)
}
}
}
}
Loading