ssh/channel/local/
channel_shell.rs

1use super::channel::Channel;
2use crate::constant::{ssh_connection_code, ssh_str};
3use crate::error::SshResult;
4use crate::model::{Data, TerminalSize};
5use std::{
6    io::{Read, Write},
7    ops::{Deref, DerefMut},
8};
9
10pub struct ChannelShell<S: Read + Write>(Channel<S>);
11
12impl<S> ChannelShell<S>
13where
14    S: Read + Write,
15{
16    pub(crate) fn open(channel: Channel<S>, tv: TerminalSize) -> SshResult<Self> {
17        // to open a shell channel, we need to request a pesudo-terminal
18        let mut channel_shell = ChannelShell(channel);
19        channel_shell.request_pty(tv)?;
20        channel_shell.get_shell()?;
21        Ok(channel_shell)
22    }
23
24    fn request_pty(&mut self, tv: TerminalSize) -> SshResult<()> {
25        let tvs = tv.fetch();
26        let mut data = Data::new();
27        data.put_u8(ssh_connection_code::CHANNEL_REQUEST)
28            .put_u32(self.server_channel_no)
29            .put_str(ssh_str::PTY_REQ)
30            .put_u8(false as u8)
31            .put_str(ssh_str::XTERM_VAR)
32            .put_u32(tvs.0)
33            .put_u32(tvs.1)
34            .put_u32(tvs.2)
35            .put_u32(tvs.3);
36        let model = [
37            128, // TTY_OP_ISPEED
38            0, 1, 0xc2, 0,   // 115200
39            129, // TTY_OP_OSPEED
40            0, 1, 0xc2, 0,    // 115200 again
41            0_u8, // TTY_OP_END
42        ];
43        data.put_u8s(&model);
44        self.send(data)
45    }
46
47    fn get_shell(&mut self) -> SshResult<()> {
48        let mut data = Data::new();
49        data.put_u8(ssh_connection_code::CHANNEL_REQUEST)
50            .put_u32(self.server_channel_no)
51            .put_str(ssh_str::SHELL)
52            .put_u8(false as u8);
53        self.send(data)
54    }
55
56    /// this method will try to read as much data as we can from the server,
57    /// but it will block until at least one packet is received
58    ///
59    pub fn read(&mut self) -> SshResult<Vec<u8>> {
60        let mut out = self.recv()?;
61        while let Ok(Some(mut data)) = self.try_recv() {
62            out.append(&mut data)
63        }
64        Ok(out)
65    }
66
67    /// this method send `buf` to the remote pty
68    ///
69    pub fn write(&mut self, buf: &[u8]) -> SshResult<()> {
70        let _ = self.send_data(buf.to_vec())?;
71        Ok(())
72    }
73}
74
75impl<S> Deref for ChannelShell<S>
76where
77    S: Read + Write,
78{
79    type Target = Channel<S>;
80    fn deref(&self) -> &Self::Target {
81        &self.0
82    }
83}
84
85impl<S> DerefMut for ChannelShell<S>
86where
87    S: Read + Write,
88{
89    fn deref_mut(&mut self) -> &mut Self::Target {
90        &mut self.0
91    }
92}