From 459296d0e21fbbfd77a60a8341194e5c39a66d6f Mon Sep 17 00:00:00 2001 From: Mike Harris Date: Tue, 2 Feb 2021 03:58:47 +1100 Subject: Expose libssh2_trace function (#209) * Expose libssh2_trace function and associated constants, to allow enabling libssh2 trace output. * set LIBSSH2_WIN32 on windows build so that gettimeofday replacement will be compiled. * libssh2_trace actually returns int, even though the documentation says it returns void. This was causing systest to fail. Changed the FFI to match the C function. Co-authored-by: eharmic --- libssh2-sys/build.rs | 8 ++++++++ libssh2-sys/lib.rs | 10 ++++++++++ src/lib.rs | 2 +- src/session.rs | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/libssh2-sys/build.rs b/libssh2-sys/build.rs index 2150148..0ec2073 100644 --- a/libssh2-sys/build.rs +++ b/libssh2-sys/build.rs @@ -39,6 +39,7 @@ fn main() { } let target = env::var("TARGET").unwrap(); + let profile = env::var("PROFILE").unwrap(); let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap()); let mut cfg = cc::Build::new(); @@ -91,6 +92,7 @@ fn main() { if target.contains("windows") { cfg.include("libssh2/win32"); cfg.define("LIBSSH2_WINCNG", None); + cfg.define("LIBSSH2_WIN32", None); cfg.file("libssh2/src/wincng.c"); } else { cfg.flag("-fvisibility=hidden"); @@ -108,6 +110,7 @@ fn main() { cfg.define("HAVE_LIBCRYPT32", None); cfg.define("HAVE_EVP_AES_128_CTR", None); cfg.define("HAVE_POLL", None); + cfg.define("HAVE_GETTIMEOFDAY", None); cfg.file("libssh2/src/openssl.c"); @@ -126,6 +129,11 @@ fn main() { cfg.define("LIBSSH2_DH_GEX_NEW", None); cfg.define("LIBSSH2_HAVE_ZLIB", None); + + if profile.contains("debug") { + cfg.define("LIBSSH2DEBUG", None); + } + println!("cargo:rerun-if-env-changed=DEP_Z_INCLUDE"); if let Some(path) = env::var_os("DEP_Z_INCLUDE") { cfg.include(path); diff --git a/libssh2-sys/lib.rs b/libssh2-sys/lib.rs index ad36642..8186fd7 100644 --- a/libssh2-sys/lib.rs +++ b/libssh2-sys/lib.rs @@ -188,6 +188,15 @@ pub const LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE: c_int = 2; pub const LIBSSH2_SESSION_BLOCK_INBOUND: c_int = 1; pub const LIBSSH2_SESSION_BLOCK_OUTBOUND: c_int = 2; +pub const LIBSSH2_TRACE_TRANS : c_int = 1<<1; +pub const LIBSSH2_TRACE_KEX : c_int = 1<<2; +pub const LIBSSH2_TRACE_AUTH : c_int = 1<<3; +pub const LIBSSH2_TRACE_CONN : c_int = 1<<4; +pub const LIBSSH2_TRACE_SCP : c_int = 1<<5; +pub const LIBSSH2_TRACE_SFTP : c_int = 1<<6; +pub const LIBSSH2_TRACE_ERROR : c_int = 1<<7; +pub const LIBSSH2_TRACE_PUBLICKEY : c_int = 1<<8; +pub const LIBSSH2_TRACE_SOCKET : c_int = 1<<9; pub enum LIBSSH2_SESSION {} pub enum LIBSSH2_AGENT {} pub enum LIBSSH2_CHANNEL {} @@ -310,6 +319,7 @@ extern "C" { pub fn libssh2_exit(); pub fn libssh2_free(sess: *mut LIBSSH2_SESSION, ptr: *mut c_void); pub fn libssh2_hostkey_hash(session: *mut LIBSSH2_SESSION, hash_type: c_int) -> *const c_char; + pub fn libssh2_trace(session: *mut LIBSSH2_SESSION, bitmask: c_int) -> c_int; // session pub fn libssh2_session_init_ex( diff --git a/src/lib.rs b/src/lib.rs index 47467c7..45f8e6b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -233,7 +233,7 @@ pub use error::{Error, ErrorCode}; pub use knownhosts::{Host, KnownHosts}; pub use listener::Listener; use session::SessionInner; -pub use session::{BlockDirections, KeyboardInteractivePrompt, Prompt, ScpFileStat, Session}; +pub use session::{BlockDirections, KeyboardInteractivePrompt, Prompt, ScpFileStat, Session, TraceFlags}; pub use sftp::{File, FileStat, FileType, OpenType}; pub use sftp::{OpenFlags, RenameFlags, Sftp}; pub use DisconnectCode::{AuthCancelledByUser, TooManyConnections}; diff --git a/src/session.rs b/src/session.rs index 33bb619..a1fa674 100644 --- a/src/session.rs +++ b/src/session.rs @@ -18,6 +18,31 @@ use util; use {raw, ByApplication, DisconnectCode, Error, ErrorCode, HostKeyType}; use {Agent, Channel, HashType, KnownHosts, Listener, MethodType, Sftp}; +bitflags! { + /// Flags which can be used with the session trace method to set + /// the trace level. + pub struct TraceFlags: c_int { + /// Authentication debugging + const AUTH = raw::LIBSSH2_TRACE_AUTH; + /// Connection layer debugging + const CONN = raw::LIBSSH2_TRACE_CONN; + /// Error debugging + const ERROR = raw::LIBSSH2_TRACE_ERROR; + /// Key exchange debugging + const KEX = raw::LIBSSH2_TRACE_KEX; + /// Public Key Debugging + const PUBLICKEY = raw::LIBSSH2_TRACE_PUBLICKEY; + /// SCP debugging + const SCP = raw::LIBSSH2_TRACE_SCP; + /// SFTP debugging + const SFTP = raw::LIBSSH2_TRACE_SFTP; + /// Socket low-level debugging + const SOCKET = raw::LIBSSH2_TRACE_SOCKET; + /// Transport layer debugging + const TRANS = raw::LIBSSH2_TRACE_TRANS; + } +} + /// Called by libssh2 to respond to some number of challenges as part of /// keyboard interactive authentication. pub trait KeyboardInteractivePrompt { @@ -1002,6 +1027,13 @@ impl Session { fn inner(&self) -> MutexGuard { self.inner.lock() } + + /// Sets the trace level for the session. + /// + pub fn trace(&self, bitmask: TraceFlags) { + let inner = self.inner(); + unsafe { let _ = raw::libssh2_trace(inner.raw, bitmask.bits() as c_int); } + } } #[cfg(unix)] -- cgit v1.2.3