Modernising the API with async traits

pmeunier
Jul 10, 2025, 6:20 PM
OBHPOIUH2CPAB2ORVMOGAAQVN4NYP6GHGTIODEQ46VUFNZIUAIRQC

Dependencies

  • [2] P5SAD7JF Version bump (+ formatting)
  • [3] 2B2UUFXG Fixing the doc tests
  • [4] DLPZJCIA Minor cleanup
  • [5] UT24SM2F Version bump
  • [6] SMUTYV2C Fixing warnings
  • [7] 6TIVIM7M Version of thrussh-keys
  • [8] G3FNNIIU Limiting the amount of messages that can be buffered while rekeying to two channel windows
  • [9] CQSPFH4H Version 0.30.4
  • [10] MCS77Y4V Making OpenSSL optional
  • [11] TAOFQAII cargo fmt
  • [12] XCNFFN6Z Thrussh-keys, version 0.19.3
  • [13] 662ZS5JF Version 0.33.2
  • [14] E2SB74SV Version 0.30.3
  • [15] ELRPPXSG Fixing conflicts
  • [16] CSYBOTTD cryptovec: use NonNull::dangling instead of potentially dangled member pointer
  • [17] 2Q3SZY2C Version bump
  • [18] D6H7OWTT Fixing the terrapin attack mitigation
  • [19] VJIXIN4T Fixing CVE-2023-48795
  • [20] 7FRJYUI6 Reboot because of a bad change
  • [21] DJT33BQE Version bump
  • [22] BRDS7STA Adding method `send_channel_msg` to client::Session, to make it easier to write handlers
  • [23] Y67GNDVB use tokio::process::Command for proxy commands
  • [24] MFMCIUMJ Fixing authentication with RSA
  • [25] PDTFLA4Y Version 0.30.7
  • [26] BWU5BDAH Thrussh-keys 0.19.5
  • [27] YSLHJU3I Add a Close construct to ChannelMsg in the server
  • [28] KGIUIQYI Executing a shell command example
  • [29] NHOSLQGG Thrussh: making OpenSSL optional
  • [30] OQZGSEWM Buffering non-kex packets received after issuing a KEXINIT
  • [31] ASD7JVBE Do not read past the size of the buffer (after Tokio 0.3)
  • [32] FT67GGO4 Version bump (Pijul and Thrussh)
  • [33] EZTTZ6OW Fixing terrapin, again
  • [34] 32GIIFWR Fixing strict mode
  • [35] UHAEQPZU Support ecdsa-sha2-nistp256 keys for authentication
  • [36] ZGJF6NR2 Make test in thrussh/src/lib pass
  • [37] 634OYCNM Tokio 0.3
  • [38] HDEDMPBT Client example
  • [39] VYDCQWSF Version 0.30.6
  • [40] Q323RFJS Version bump
  • [41] R5J3MB56 Client newkeys was not always resetting the sequence counter
  • [42] AWVLXGAW Removing anyhows on Windows
  • [43] 63PFETND fix compile errors in tests and examples
  • [44] 7Y2ROIVZ Version bump
  • [45] WXZWQLGL Correct negotiation without OpenSSL
  • [46] Y2367J3D Add test for ecdsa public key
  • [47] KNLLUDOI Correct usage of `tokio::select!`
  • [48] TFYJ3P2A Version 0.30.8/0.19.4, and solving conflicts
  • [49] 2WEO7OZL Version updates: getting rid of anyhow + moving to Tokio 1.0
  • [50] CWHVPLXN Version bump
  • [51] ORSEEVB5 Version bump
  • [52] 2VTUKRLJ Version
  • [53] EUHO3DAZ Send a SSH_MSG_EXT_INFO with server-sig-algs when the client indicates they support extensions by sending ext-info-c. This allows modern clients that don't do ssh-rsa anymore because of sha1 to still use RSA keys with sha2.

Change contents

  • replacement in thrussh-keys/src/lib.rs at line 30
    [7.24519][7.24519:24579]()
    //! let dir = tempdir::TempDir::new("thrussh").unwrap();
    [7.24519]
    [7.24579]
    //! let dir = tempfile::TempDir::with_prefix("thrussh").unwrap();
  • edit in thrussh-keys/src/lib.rs at line 436
    [7.35848][7.35848:35874]()
    extern crate tempdir;
  • replacement in thrussh-keys/src/lib.rs at line 539
    [7.39120][7.39120:39181]()
    let dir = tempdir::TempDir::new("thrussh").unwrap();
    [7.39120]
    [7.39181]
    let dir = tempfile::TempDir::with_prefix("thrussh").unwrap();
  • replacement in thrussh-keys/src/lib.rs at line 828
    [7.54026][7.54026:54087]()
    let dir = tempdir::TempDir::new("thrussh").unwrap();
    [7.54026]
    [7.54087]
    let dir = tempfile::TempDir::with_prefix("thrussh").unwrap();
  • replacement in thrussh-keys/src/lib.rs at line 903
    [7.55827][7.55827:55888]()
    let dir = tempdir::TempDir::new("thrussh").unwrap();
    [7.55827]
    [7.55888]
    let dir = tempfile::TempDir::with_prefix("thrussh").unwrap();
  • replacement in thrussh-keys/Cargo.toml at line 3
    [7.157057][5.0:19]()
    version = "0.22.1"
    [7.157057]
    [7.157076]
    version = "0.23.1"
  • replacement in thrussh-keys/Cargo.toml at line 37
    [7.157904][7.157904:157924]()
    cryptovec = "0.6.0"
    [7.157904]
    [7.255]
    cryptovec = "0.7.0"
  • replacement in thrussh-keys/Cargo.toml at line 60
    [7.158207][7.345:364](),[7.364][7.158226:158240](),[7.158226][7.158226:158240]()
    env_logger = "0.8"
    tempdir="0.3"
    [7.158207]
    env_logger = "0.11"
    tempfile="3.20"
  • edit in thrussh/src/session.rs at line 17
    [7.172236][7.172236:172286]()
    use crate::{auth, cipher, kex, msg, negotiation};
  • edit in thrussh/src/session.rs at line 18
    [7.172339]
    [7.172339]
    use crate::{auth, cipher, kex, msg, negotiation};
  • replacement in thrussh/src/session.rs at line 313
    [7.182302][7.182302:182541](),[7.182541][4.39:63]()
    let packet = self
    .compress
    .compress(
    &self.write[(self.write_cursor + 4)..(self.write_cursor + 4 + len)],
    &mut self.compress_buffer,
    )?;
    [7.182302]
    [7.182594]
    let packet = self.compress.compress(
    &self.write[(self.write_cursor + 4)..(self.write_cursor + 4 + len)],
    &mut self.compress_buffer,
    )?;
  • replacement in thrussh/src/server/mod.rs at line 132
    [7.207677][7.207677:207704]()
    pub trait Handler: Sized {
    [7.207677]
    [7.4983]
    pub trait Handler: Sized + Send {
  • edit in thrussh/src/server/mod.rs at line 134
    [7.5026][7.207704:207795](),[7.207704][7.207704:207795](),[7.207795][7.5027:5107](),[7.5107][7.207877:207944](),[7.207877][7.207877:207944](),[7.207944][7.5108:5191](),[7.5191][7.208029:208103](),[7.208029][7.208029:208103](),[7.208103][7.5192:5281](),[7.5281][7.208194:208690](),[7.208194][7.208194:208690]()
    /// The type of authentications, which can be a future ultimately
    /// resolving to
    type FutureAuth: Future<Output = Result<(Self, Auth), Self::Error>> + Send;
    /// The type of units returned by some parts of this handler.
    type FutureUnit: Future<Output = Result<(Self, Session), Self::Error>> + Send;
    /// The type of future bools returned by some parts of this handler.
    type FutureBool: Future<Output = Result<(Self, Session, bool), Self::Error>> + Send;
    /// Convert an `Auth` to `Self::FutureAuth`. This is used to
    /// produce the default handlers.
    fn finished_auth(self, auth: Auth) -> Self::FutureAuth;
    /// Convert a `bool` to `Self::FutureBool`. This is used to
    /// produce the default handlers.
    fn finished_bool(self, b: bool, session: Session) -> Self::FutureBool;
    /// Produce a `Self::FutureUnit`. This is used to produce the
    /// default handlers.
    fn finished(self, session: Session) -> Self::FutureUnit;
  • replacement in thrussh/src/server/mod.rs at line 139
    [7.208911][7.208911:209009]()
    fn auth_none(self, user: &str) -> Self::FutureAuth {
    self.finished_auth(Auth::Reject)
    [7.208911]
    [7.209009]
    fn auth_none(
    self,
    user: &str,
    ) -> impl Future<Output = Result<(Self, Auth), Self::Error>> + Send {
    async { Ok((self, Auth::Reject)) }
  • replacement in thrussh/src/server/mod.rs at line 151
    [7.209248][7.209248:209366]()
    fn auth_password(self, user: &str, password: &str) -> Self::FutureAuth {
    self.finished_auth(Auth::Reject)
    [7.209248]
    [7.209366]
    fn auth_password(
    self,
    user: &str,
    password: &str,
    ) -> impl Future<Output = Result<(Self, Auth), Self::Error>> + Send {
    async { Ok((self, Auth::Reject)) }
  • replacement in thrussh/src/server/mod.rs at line 167
    [7.209818][7.209818:209950]()
    fn auth_publickey(self, user: &str, public_key: &key::PublicKey) -> Self::FutureAuth {
    self.finished_auth(Auth::Reject)
    [7.209818]
    [7.209950]
    fn auth_publickey(
    self,
    user: &str,
    public_key: &key::PublicKey,
    ) -> impl Future<Output = Result<(Self, Auth), Self::Error>> + Send {
    async { Ok((self, Auth::Reject)) }
  • replacement in thrussh/src/server/mod.rs at line 185
    [7.210331][7.210331:210400]()
    ) -> Self::FutureAuth {
    self.finished_auth(Auth::Reject)
    [7.210331]
    [7.210400]
    ) -> impl Future<Output = Result<(Self, Auth), Self::Error>> + Send {
    async { Ok((self, Auth::Reject)) }
  • replacement in thrussh/src/server/mod.rs at line 191
    [7.210487][7.210487:210605]()
    fn channel_close(self, channel: ChannelId, session: Session) -> Self::FutureUnit {
    self.finished(session)
    [7.210487]
    [7.210605]
    fn channel_close(
    self,
    channel: ChannelId,
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 201
    [7.210698][7.210698:210814]()
    fn channel_eof(self, channel: ChannelId, session: Session) -> Self::FutureUnit {
    self.finished(session)
    [7.210698]
    [7.210814]
    fn channel_eof(
    self,
    channel: ChannelId,
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 211
    [7.210906][7.210906:211031]()
    fn channel_open_session(self, channel: ChannelId, session: Session) -> Self::FutureUnit {
    self.finished(session)
    [7.210906]
    [7.211031]
    fn channel_open_session(
    self,
    channel: ChannelId,
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 227
    [7.211276][7.211276:211335]()
    ) -> Self::FutureUnit {
    self.finished(session)
    [7.211276]
    [7.211335]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 241
    [7.211646][7.211646:211705]()
    ) -> Self::FutureUnit {
    self.finished(session)
    [7.211646]
    [7.211705]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 248
    [7.211852][7.211852:211974]()
    fn data(self, channel: ChannelId, data: &[u8], session: Session) -> Self::FutureUnit {
    self.finished(session)
    [7.211852]
    [7.211974]
    fn data(
    self,
    channel: ChannelId,
    data: &[u8],
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 268
    [7.212366][7.212366:212425]()
    ) -> Self::FutureUnit {
    self.finished(session)
    [7.212366]
    [7.212425]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 280
    [7.212688][7.212688:212716]()
    ) -> Self::FutureUnit {
    [7.212688]
    [7.212716]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/server/mod.rs at line 284
    [7.212828][7.212828:212859]()
    self.finished(session)
    [7.212828]
    [7.212859]
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 307
    [7.213446][7.213446:213505]()
    ) -> Self::FutureUnit {
    self.finished(session)
    [7.213446]
    [7.213505]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 321
    [7.213807][7.213807:213866]()
    ) -> Self::FutureUnit {
    self.finished(session)
    [7.213807]
    [7.213866]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 335
    [7.214218][7.214218:214277]()
    ) -> Self::FutureUnit {
    self.finished(session)
    [7.214218]
    [7.214277]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 341
    [7.214352][7.214352:214470]()
    fn shell_request(self, channel: ChannelId, session: Session) -> Self::FutureUnit {
    self.finished(session)
    [7.214352]
    [7.214470]
    fn shell_request(
    self,
    channel: ChannelId,
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 352
    [7.214636][7.214636:214766]()
    fn exec_request(self, channel: ChannelId, data: &[u8], session: Session) -> Self::FutureUnit {
    self.finished(session)
    [7.214636]
    [7.214766]
    fn exec_request(
    self,
    channel: ChannelId,
    data: &[u8],
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 369
    [7.215009][7.215009:215068]()
    ) -> Self::FutureUnit {
    self.finished(session)
    [7.215009]
    [7.215068]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 383
    [7.215364][7.215364:215423]()
    ) -> Self::FutureUnit {
    self.finished(session)
    [7.215364]
    [7.215423]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 390
    [7.215560][7.215560:215689]()
    fn signal(self, channel: ChannelId, signal_name: Sig, session: Session) -> Self::FutureUnit {
    self.finished(session)
    [7.215560]
    [7.215689]
    fn signal(
    self,
    channel: ChannelId,
    signal_name: Sig,
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/server/mod.rs at line 402
    [7.215840][7.215840:215976]()
    fn tcpip_forward(self, address: &str, port: u32, session: Session) -> Self::FutureBool {
    self.finished_bool(false, session)
    [7.215840]
    [7.215976]
    fn tcpip_forward(
    self,
    address: &str,
    port: u32,
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session, bool), Self::Error>> + Send {
    async { Ok((self, session, false)) }
  • edit in thrussh/src/server/mod.rs at line 410
    [7.215982]
    [7.215982]
  • replacement in thrussh/src/server/mod.rs at line 414
    [7.216138][7.216138:216281]()
    fn cancel_tcpip_forward(self, address: &str, port: u32, session: Session) -> Self::FutureBool {
    self.finished_bool(false, session)
    [7.216138]
    [7.216281]
    fn cancel_tcpip_forward(
    self,
    address: &str,
    port: u32,
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session, bool), Self::Error>> + Send {
    async { Ok((self, session, false)) }
  • replacement in thrussh/src/server/mod.rs at line 701
    [7.831][7.831:889]()
    return Err(Error::KexInit.into())
    [7.831]
    [7.889]
    return Err(Error::KexInit.into());
  • replacement in thrussh/src/negotiation.rs at line 15
    [7.268986][7.268986:269024]()
    use crate::{cipher, kex, msg, Error};
    [7.268986]
    [7.269024]
    use crate::{Error, cipher, kex, msg};
  • edit in thrussh/src/negotiation.rs at line 57
    [7.270075]
    [7.15271]
    pub fn compressed(self) -> Self {
    Self {
    compression: &["zlib", "zlib@openssh.com"],
    ..self
    }
    }
  • replacement in thrussh/src/negotiation.rs at line 235
    [7.1293][7.2175:2259](),[7.2175][7.2175:2259]()
    debug!("strict {:?} {:?}", client_supports_strict, server_supports_strict);
    [7.1293]
    [7.272078]
    debug!(
    "strict {:?} {:?}",
    client_supports_strict, server_supports_strict
    );
  • replacement in thrussh/src/negotiation.rs at line 301
    [6.280][7.1470:1551](),[7.1706][7.1470:1551]()
    strict_kex: client_supports_strict && server_supports_strict
    [6.280]
    [7.274587]
    strict_kex: client_supports_strict && server_supports_strict,
  • edit in thrussh/src/lib.rs at line 83
    [3.36][7.281500:281781](),[7.281500][7.281500:281781]()
    //! type FutureAuth = futures::future::Ready<Result<(Self, server::Auth), anyhow::Error>>;
    //! type FutureUnit = futures::future::Ready<Result<(Self, Session), anyhow::Error>>;
    //! type FutureBool = futures::future::Ready<Result<(Self, Session, bool), anyhow::Error>>;
  • replacement in thrussh/src/lib.rs at line 84
    [7.281785][7.281785:282272]()
    //! fn finished_auth(mut self, auth: Auth) -> Self::FutureAuth {
    //! futures::future::ready(Ok((self, auth)))
    //! }
    //! fn finished_bool(self, b: bool, s: Session) -> Self::FutureBool {
    //! futures::future::ready(Ok((self, s, b)))
    //! }
    //! fn finished(self, s: Session) -> Self::FutureUnit {
    //! futures::future::ready(Ok((self, s)))
    //! }
    //! fn channel_open_session(self, channel: ChannelId, session: Session) -> Self::FutureUnit {
    [7.281785]
    [7.282272]
    //! fn channel_open_session(self, channel: ChannelId, session: Session) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/lib.rs at line 89
    [7.282434][7.282434:282469]()
    //! self.finished(session)
    [7.282434]
    [7.282469]
    //! async { Ok((self, session)) }
  • replacement in thrussh/src/lib.rs at line 91
    [7.282479][7.282479:282615]()
    //! fn auth_publickey(self, _: &str, _: &key::PublicKey) -> Self::FutureAuth {
    //! self.finished_auth(server::Auth::Accept)
    [7.282479]
    [7.282615]
    //! fn auth_publickey(self, _: &str, _: &key::PublicKey) -> impl Future<Output = Result<(Self, Auth), Self::Error>> + Send {
    //! async { Ok((self, server::Auth::Accept)) }
  • replacement in thrussh/src/lib.rs at line 94
    [7.282625][7.282625:282724]()
    //! fn data(self, channel: ChannelId, data: &[u8], mut session: Session) -> Self::FutureUnit {
    [7.282625]
    [7.282724]
    //! fn data(self, channel: ChannelId, data: &[u8], mut session: Session) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/lib.rs at line 104
    [7.283102][7.283102:283137]()
    //! self.finished(session)
    [7.283102]
    [7.283137]
    //! async { Ok((self, session)) }
  • edit in thrussh/src/lib.rs at line 159
    [3.72][7.284875:285058](),[7.284875][7.284875:285058]()
    //! type FutureUnit = futures::future::Ready<Result<(Self, client::Session), anyhow::Error>>;
    //! type FutureBool = futures::future::Ready<Result<(Self, bool), anyhow::Error>>;
  • replacement in thrussh/src/lib.rs at line 160
    [7.285062][7.285062:285409]()
    //! fn finished_bool(self, b: bool) -> Self::FutureBool {
    //! futures::future::ready(Ok((self, b)))
    //! }
    //! fn finished(self, session: client::Session) -> Self::FutureUnit {
    //! futures::future::ready(Ok((self, session)))
    //! }
    //! fn check_server_key(self, server_public_key: &key::PublicKey) -> Self::FutureBool {
    [7.285062]
    [7.285409]
    //! fn check_server_key(self, server_public_key: &key::PublicKey) -> impl Future<Output = Result<(Self, bool), Self::Error>> + Send {
  • replacement in thrussh/src/lib.rs at line 162
    [7.285475][7.285475:285511]()
    //! self.finished_bool(true)
    [7.285475]
    [7.285511]
    //! async { Ok((self, true)) }
  • replacement in thrussh/src/lib.rs at line 164
    [7.285520][7.285520:285670]()
    //! fn channel_open_confirmation(self, channel: ChannelId, max_packet_size: u32, window_size: u32, session: client::Session) -> Self::FutureUnit {
    [7.285520]
    [7.285670]
    //!
    //! fn channel_open_confirmation(self, channel: ChannelId, max_packet_size: u32, window_size: u32, session: client::Session) -> impl Future<Output = Result<(Self, client::Session), Self::Error>> + Send {
  • replacement in thrussh/src/lib.rs at line 167
    [7.285735][7.285735:285769]()
    //! self.finished(session)
    [7.285735]
    [7.285769]
    //! async { Ok((self, session)) }
  • replacement in thrussh/src/lib.rs at line 169
    [7.285778][7.285778:285880]()
    //! fn data(self, channel: ChannelId, data: &[u8], session: client::Session) -> Self::FutureUnit {
    [7.285778]
    [7.285880]
    //!
    //! fn data(self, channel: ChannelId, data: &[u8], session: client::Session) -> impl Future<Output = Result<(Self, client::Session), Self::Error>> + Send {
  • replacement in thrussh/src/lib.rs at line 172
    [7.285967][7.285967:286001]()
    //! self.finished(session)
    [7.285967]
    [7.286001]
    //! async { Ok((self, session)) }
  • replacement in thrussh/src/lib.rs at line 635
    [7.298620][7.0:53]()
    use super::server::{Auth, Server as _, Session};
    [7.298620]
    [7.298660]
    use super::server::{Server as _, Session};
  • edit in thrussh/src/lib.rs at line 641
    [7.14133]
    [7.298786]
    #[cfg(feature = "flate2")]
  • edit in thrussh/src/lib.rs at line 646
    [7.177][7.177:246]()
    let client_pubkey = Arc::new(client_key.clone_public_key());
  • replacement in thrussh/src/lib.rs at line 647
    [7.298][7.298:348]()
    config.preferred = Preferred::COMPRESSED;
    [7.298]
    [7.348]
    config.preferred = config.preferred.compressed();
  • edit in thrussh/src/lib.rs at line 655
    [7.684][7.684:711]()
    client_pubkey,
  • replacement in thrussh/src/lib.rs at line 669
    [7.1212][7.1212:1262]()
    config.preferred = Preferred::COMPRESSED;
    [7.1212]
    [7.300424]
    config.preferred = config.preferred.compressed();
  • edit in thrussh/src/lib.rs at line 694
    [7.301232][7.301232:301290]()
    client_pubkey: Arc<thrussh_keys::key::PublicKey>,
  • replacement in thrussh/src/lib.rs at line 709
    [7.14169][7.14169:14444](),[7.14444][7.301942:302426](),[7.301942][7.301942:302426]()
    type FutureAuth = futures::future::Ready<Result<(Self, server::Auth), Self::Error>>;
    type FutureUnit = futures::future::Ready<Result<(Self, Session), Self::Error>>;
    type FutureBool = futures::future::Ready<Result<(Self, Session, bool), Self::Error>>;
    fn finished_auth(self, auth: Auth) -> Self::FutureAuth {
    futures::future::ready(Ok((self, auth)))
    }
    fn finished_bool(self, b: bool, s: Session) -> Self::FutureBool {
    futures::future::ready(Ok((self, s, b)))
    }
    fn finished(self, s: Session) -> Self::FutureUnit {
    futures::future::ready(Ok((self, s)))
    }
    fn channel_open_session(self, channel: ChannelId, session: Session) -> Self::FutureUnit {
    [7.14169]
    [7.302426]
    fn channel_open_session(
    self,
    channel: ChannelId,
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Error>> + Send {
  • replacement in thrussh/src/lib.rs at line 718
    [7.302588][7.302588:302623]()
    self.finished(session)
    [7.302588]
    [7.302623]
    async { Ok((self, session)) }
  • replacement in thrussh/src/lib.rs at line 720
    [7.302633][7.302633:302730]()
    fn auth_publickey(self, _: &str, _: &thrussh_keys::key::PublicKey) -> Self::FutureAuth {
    [7.302633]
    [7.302730]
    fn auth_publickey(
    self,
    _: &str,
    _: &thrussh_keys::key::PublicKey,
    ) -> impl Future<Output = Result<(Self, server::Auth), Self::Error>> {
  • replacement in thrussh/src/lib.rs at line 726
    [7.302768][7.302768:302821]()
    self.finished_auth(server::Auth::Accept)
    [7.302768]
    [7.302821]
    async { Ok((self, server::Auth::Accept)) }
  • replacement in thrussh/src/lib.rs at line 728
    [7.302831][7.1832:1931]()
    fn data(self, channel: ChannelId, data: &[u8], mut session: Session) -> Self::FutureUnit {
    [7.302831]
    [7.302927]
    fn data(
    self,
    channel: ChannelId,
    data: &[u8],
    mut session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/lib.rs at line 736
    [7.1996][7.302996:303031](),[7.302996][7.302996:303031]()
    self.finished(session)
    [7.1996]
    [7.303031]
    async { Ok((self, session)) }
  • edit in thrussh/src/lib.rs at line 744
    [7.14480][7.14480:14661](),[7.14661][7.303293:303556](),[7.303293][7.303293:303556]()
    type FutureUnit = futures::future::Ready<Result<(Self, client::Session), Self::Error>>;
    type FutureBool = futures::future::Ready<Result<(Self, bool), Self::Error>>;
    fn finished_bool(self, b: bool) -> Self::FutureBool {
    futures::future::ready(Ok((self, b)))
    }
    fn finished(self, session: client::Session) -> Self::FutureUnit {
    futures::future::ready(Ok((self, session)))
    }
  • replacement in thrussh/src/lib.rs at line 747
    [7.303665][7.303665:303697]()
    ) -> Self::FutureBool {
    [7.303665]
    [7.303697]
    ) -> impl Future<Output = Result<(Self, bool), Self::Error>> + Send {
  • replacement in thrussh/src/lib.rs at line 749
    [7.303764][7.303764:303801]()
    self.finished_bool(true)
    [7.303764]
    [7.304472]
    async { Ok((self, true)) }
  • edit in thrussh/src/client/mod.rs at line 24
    [7.335846][7.335846:335882]()
    use futures::task::{Context, Poll};
  • edit in thrussh/src/client/mod.rs at line 25
    [7.335903]
    [7.335903]
    use futures::task::{Context, Poll};
  • replacement in thrussh/src/client/mod.rs at line 40
    [7.336231][7.336231:336256]()
    use crate::{msg, Error};
    [7.336231]
    [7.336256]
    use crate::{Error, msg};
  • replacement in thrussh/src/client/mod.rs at line 1224
    [7.373210][7.373210:373237]()
    pub trait Handler: Sized {
    [7.373210]
    [7.19053]
    pub trait Handler: Sized + Send {
  • edit in thrussh/src/client/mod.rs at line 1226
    [7.19096][7.373237:373352](),[7.373237][7.373237:373352](),[7.373352][7.19097:19177](),[7.19177][7.373434:373545](),[7.373434][7.373434:373545](),[7.373545][7.19178:19261](),[7.19261][7.373630:373790](),[7.373630][7.373630:373790]()
    /// A future ultimately resolving into a boolean, which can be
    /// returned by some parts of this handler.
    type FutureBool: Future<Output = Result<(Self, bool), Self::Error>> + Send;
    /// A future ultimately resolving into unit, which can be
    /// returned by some parts of this handler.
    type FutureUnit: Future<Output = Result<(Self, Session), Self::Error>> + Send;
    /// Convert a `bool` to `Self::FutureBool`. This is used to
    /// produce the default handlers.
    fn finished_bool(self, b: bool) -> Self::FutureBool;
  • edit in thrussh/src/client/mod.rs at line 1227
    [7.373791][7.373791:373945]()
    /// Produce a `Self::FutureUnit`. This is used to produce the
    /// default handlers.
    fn finished(self, session: Session) -> Self::FutureUnit;
  • replacement in thrussh/src/client/mod.rs at line 1234
    [7.374243][7.374243:374353]()
    fn auth_banner(self, banner: &str, session: Session) -> Self::FutureUnit {
    self.finished(session)
    [7.374243]
    [7.374353]
    fn auth_banner(
    self,
    banner: &str,
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/client/mod.rs at line 1246
    [7.374574][7.374574:374696]()
    fn check_server_key(self, server_public_key: &key::PublicKey) -> Self::FutureBool {
    self.finished_bool(false)
    [7.374574]
    [7.374696]
    fn check_server_key(
    self,
    server_public_key: &key::PublicKey,
    ) -> impl Future<Output = Result<(Self, bool), Self::Error>> + Send {
    async { Ok((self, false)) }
  • replacement in thrussh/src/client/mod.rs at line 1263
    [7.375070][7.375070:375098]()
    ) -> Self::FutureUnit {
    [7.375070]
    [7.375098]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/client/mod.rs at line 1275
    [7.375444][7.375444:375475]()
    self.finished(session)
    [7.375444]
    [7.375475]
    async { Ok((self, session)) }
  • replacement in thrussh/src/client/mod.rs at line 1280
    [7.375561][7.375561:375650]()
    fn channel_success(self, channel: ChannelId, session: Session) -> Self::FutureUnit {
    [7.375561]
    [7.375650]
    fn channel_success(
    self,
    channel: ChannelId,
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/client/mod.rs at line 1289
    [7.375816][7.375816:375847]()
    self.finished(session)
    [7.375816]
    [7.375847]
    async { Ok((self, session)) }
  • replacement in thrussh/src/client/mod.rs at line 1294
    [7.375934][7.375934:376025]()
    fn channel_close(self, channel: ChannelId, mut session: Session) -> Self::FutureUnit {
    [7.375934]
    [7.376025]
    fn channel_close(
    self,
    channel: ChannelId,
    mut session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/client/mod.rs at line 1300
    [7.376068][7.376068:376099]()
    self.finished(session)
    [7.376068]
    [7.376099]
    async { Ok((self, session)) }
  • replacement in thrussh/src/client/mod.rs at line 1305
    [7.376192][7.376192:376277]()
    fn channel_eof(self, channel: ChannelId, session: Session) -> Self::FutureUnit {
    [7.376192]
    [7.376277]
    fn channel_eof(
    self,
    channel: ChannelId,
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/client/mod.rs at line 1314
    [7.376439][7.376439:376470]()
    self.finished(session)
    [7.376439]
    [7.376470]
    async { Ok((self, session)) }
  • replacement in thrussh/src/client/mod.rs at line 1326
    [7.376767][7.376767:376795]()
    ) -> Self::FutureUnit {
    [7.376767]
    [7.376795]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/client/mod.rs at line 1329
    [7.376908][7.376908:376939]()
    self.finished(session)
    [7.376908]
    [7.376939]
    async { Ok((self, session)) }
  • replacement in thrussh/src/client/mod.rs at line 1342
    [7.377254][7.377254:377313]()
    ) -> Self::FutureUnit {
    self.finished(session)
    [7.377254]
    [7.377313]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
    async { Ok((self, session)) }
  • replacement in thrussh/src/client/mod.rs at line 1351
    [7.377615][7.377615:377706]()
    fn data(self, channel: ChannelId, data: &[u8], session: Session) -> Self::FutureUnit {
    [7.377615]
    [7.377706]
    fn data(
    self,
    channel: ChannelId,
    data: &[u8],
    session: Session,
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/client/mod.rs at line 1363
    [7.377932][7.377932:377963]()
    self.finished(session)
    [7.377932]
    [7.377963]
    async { Ok((self, session)) }
  • replacement in thrussh/src/client/mod.rs at line 1377
    [7.378394][7.378394:378422]()
    ) -> Self::FutureUnit {
    [7.378394]
    [7.378422]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/client/mod.rs at line 1385
    [7.378677][7.378677:378708]()
    self.finished(session)
    [7.378677]
    [7.378708]
    async { Ok((self, session)) }
  • replacement in thrussh/src/client/mod.rs at line 1397
    [7.379047][7.379047:379075]()
    ) -> Self::FutureUnit {
    [7.379047]
    [7.379075]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/client/mod.rs at line 1402
    [7.379259][7.379259:379290]()
    self.finished(session)
    [7.379259]
    [7.379290]
    async { Ok((self, session)) }
  • replacement in thrussh/src/client/mod.rs at line 1412
    [7.379509][7.379509:379537]()
    ) -> Self::FutureUnit {
    [7.379509]
    [7.379537]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/client/mod.rs at line 1417
    [7.379722][7.379722:379753]()
    self.finished(session)
    [7.379722]
    [7.379753]
    async { Ok((self, session)) }
  • replacement in thrussh/src/client/mod.rs at line 1430
    [7.380044][7.380044:380072]()
    ) -> Self::FutureUnit {
    [7.380044]
    [7.380072]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/client/mod.rs at line 1440
    [7.380417][7.380417:380448]()
    self.finished(session)
    [7.380417]
    [7.380448]
    async { Ok((self, session)) }
  • replacement in thrussh/src/client/mod.rs at line 1454
    [7.380902][7.380902:380930]()
    ) -> Self::FutureUnit {
    [7.380902]
    [7.380930]
    ) -> impl Future<Output = Result<(Self, Session), Self::Error>> + Send {
  • replacement in thrussh/src/client/mod.rs at line 1462
    [7.381247][7.381247:381278]()
    self.finished(session)
    [7.381247]
    [7.381278]
    async { Ok((self, session)) }
  • edit in thrussh/src/client/encrypted.rs at line 88
    [7.744][7.744:745]()
  • edit in thrussh/src/cipher/mod.rs at line 15
    [7.409686][7.409686:409719]()
    use crate::sshbuffer::SSHBuffer;
  • edit in thrussh/src/cipher/mod.rs at line 16
    [7.409737]
    [7.409737]
    use crate::sshbuffer::SSHBuffer;
  • replacement in thrussh/examples/remote_shell_call.rs at line 22
    [7.526][7.526:1060]()
    type FutureUnit = futures::future::Ready<Result<(Self, client::Session), Self::Error>>;
    type FutureBool = futures::future::Ready<Result<(Self, bool), Self::Error>>;
    fn finished_bool(self, b: bool) -> Self::FutureBool {
    futures::future::ready(Ok((self, b)))
    }
    fn finished(self, session: client::Session) -> Self::FutureUnit {
    futures::future::ready(Ok((self, session)))
    }
    fn check_server_key(self, _server_public_key: &key::PublicKey) -> Self::FutureBool {
    self.finished_bool(true)
    [7.526]
    [7.1060]
    fn check_server_key(
    self,
    _server_public_key: &key::PublicKey,
    ) -> impl Future<Output = Result<(Self, bool), Self::Error>> + Send {
    async { Ok((self, true)) }
  • replacement in thrussh/examples/client.rs at line 15
    [7.24053][7.24053:24226](),[7.24226][7.449:776](),[7.449][7.449:776]()
    type FutureUnit = futures::future::Ready<Result<(Self, client::Session), Self::Error>>;
    type FutureBool = futures::future::Ready<Result<(Self, bool), Self::Error>>;
    fn finished_bool(self, b: bool) -> Self::FutureBool {
    futures::future::ready(Ok((self, b)))
    }
    fn finished(self, session: client::Session) -> Self::FutureUnit {
    futures::future::ready(Ok((self, session)))
    }
    fn check_server_key(self, server_public_key: &key::PublicKey) -> Self::FutureBool {
    [7.24053]
    [7.776]
    fn check_server_key(
    self,
    server_public_key: &key::PublicKey,
    ) -> impl Future<Output = Result<(Self, bool), Self::Error>> + Send {
  • replacement in thrussh/examples/client.rs at line 20
    [7.839][7.839:872]()
    self.finished_bool(true)
    [7.839]
    [7.872]
    async { Ok((self, true)) }
  • replacement in thrussh/Cargo.toml at line 5
    [7.426214][6.373:392]()
    version = "0.35.6"
    [7.426214]
    [7.426233]
    version = "0.36.1"
  • replacement in thrussh/Cargo.toml at line 39
    [7.426966][7.426966:426983]()
    edition = "2018"
    [7.426966]
    [7.426983]
    edition = "2024"
  • replacement in thrussh/Cargo.toml at line 50
    [7.24259][7.40:104]()
    thrussh-keys = { version = "0.22.0", path = "../thrussh-keys" }
    [7.24259]
    [7.1877]
    thrussh-keys = { version = "0.23.1", path = "../thrussh-keys" }
  • replacement in thrussh/Cargo.toml at line 53
    [7.427148][7.427148:427168]()
    cryptovec = "0.6.0"
    [7.427148]
    [7.1053]
    cryptovec = "0.7.0"
  • replacement in thrussh/Cargo.toml at line 64
    [7.427395][7.427395:427414]()
    env_logger = "0.7"
    [7.427395]
    [7.24391]
    env_logger = "0.11"
  • replacement in cryptovec/src/lib.rs at line 147
    [7.431922][7.431922:431976]()
    libc::mlock(ptr as *const c_void, len as size_t);
    [7.431922]
    [7.431976]
    unsafe { libc::mlock(ptr as *const c_void, len as size_t) };
  • replacement in cryptovec/src/lib.rs at line 151
    [7.432047][7.432047:432103]()
    libc::munlock(ptr as *const c_void, len as size_t);
    [7.432047]
    [7.432103]
    unsafe { libc::munlock(ptr as *const c_void, len as size_t) };
  • replacement in cryptovec/Cargo.toml at line 4
    [7.440768][2.45:63]()
    version = "0.6.1"
    [7.440768]
    [7.440786]
    version = "0.7.0"
  • edit in cryptovec/Cargo.toml at line 10
    [7.441004]
    [7.441004]
    edition = "2024"
  • edit in Cargo.toml at line 4
    [7.453847]
    [7.453847]
    resolver = "3"