1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
//! Dependencies
//! ```
//! ssh-rs = "0.2.1"
//! ```
//!
//! ## Connection method:
//!
//! ### 1. Password:
//! ```rust
//! use ssh_rs::{Session, ssh};
//!
//! fn main() {
//!     let mut session: Session = ssh::create_session();
//!     session.set_user_and_password("user", "password");
//!     session.connect("ip:port").unwrap();
//! }
//! ```
//!
//! ### 2. Public key:
//! #### Currently, only `RSA-PKCS#1-PEM` type encrypted files with the encryption format `-----BEGIN RSA PRIVATE KEY-----` are supported.
//!
//! #### 1. Use key file path:
//! ```rust
//! use ssh_rs::{Session, ssh};
//! use ssh_rs::key_pair::KeyPairType;
//!
//! fn main() {
//!     let mut session: Session = ssh::create_session();
//!     // pem format key path -> /xxx/xxx/id_rsa
//!     // KeyPairType::SshRsa -> Rsa type algorithm, currently only supports rsa.
//!     session.set_user_and_key_pair_path("user", "pem format key path", KeyPairType::SshRsa).unwrap();
//!     session.connect("ip:port").unwrap();
//! }
//! ```
//!
//! #### 2. Use key string:
//! ```rust
//! use ssh_rs::{Session, ssh};
//! use ssh_rs::key_pair::KeyPairType;
//!
//! fn main() {
//!     let mut session: Session = ssh::create_session();
//!     // pem format key string:
//!     //      -----BEGIN RSA PRIVATE KEY-----
//!     //          xxxxxxxxxxxxxxxxxxxxx
//!     //      -----END RSA PRIVATE KEY-----
//!     // KeyPairType::SshRsa -> Rsa type algorithm, currently only supports rsa.
//!     session.set_user_and_key_pair("user", "pem format key string", KeyPairType::SshRsa).unwrap();
//!     session.connect("ip:port").unwrap();
//! }
//! ```
//!
//! ## Enable global logging:
//!
//! ```rust
//! use ssh_rs::{Session, ssh};
//!
//! fn main() {
//!     // is_enable_log Whether to enable global logging
//!     // The default is false(Do not enable)
//!     // Can be set as true (enable)
//!     ssh::is_enable_log(true);
//!
//!     let mut session: Session = ssh::create_session();
//!     session.set_user_and_password("user", "password");
//!     session.connect("ip:port").unwrap();
//! }
//! ```
//!
//!
//! ## Set timeout:
//!
//! ```rust
//! use ssh_rs::{Session, ssh};
//!
//! fn main() {
//!     let mut session: Session = ssh::create_session();
//!     // set_timeout
//!     // The unit is seconds
//!     // The default timeout is 30 seconds
//!     session.set_timeout(15);
//!     session.set_user_and_password("user", "password");
//!     session.connect("ip:port").unwrap();
//! }
//! ```
//!
//!
//! ## How to use:
//!
//! ### Currently only supports exec shell scp these three functions.
//!
//! ### 1. exec
//!
//! ```rust
//! use ssh_rs::{ChannelExec, Session, ssh};
//!
//! fn main() {
//!     let mut session: Session = session();
//!     // Usage 1
//!     let exec: ChannelExec = session.open_exec().unwrap();
//!     let vec: Vec<u8> = exec.send_command("ls -all").unwrap();
//!     println!("{}", String::from_utf8(vec).unwrap());
//!     // Usage 2
//!     let channel = session.open_channel().unwrap();
//!     let exec = channel.open_exec().unwrap();
//!     let vec: Vec<u8> = exec.send_command("ls -all").unwrap();
//!     println!("{}", String::from_utf8(vec).unwrap());
//!     // Close session.
//!     session.close().unwrap();
//! }
//! ```
//!
//! ### 2. shell
//!
//! ```rust
//! use std::thread::sleep;
//! use std::time::Duration;
//! use ssh_rs::{Channel, ChannelShell, Session, ssh};
//!
//! fn main() {
//!     let mut session: Session = session();
//!     // Usage 1
//!     let mut shell: ChannelShell = session.open_shell().unwrap();
//!     run_shell(&mut shell);
//!     // Usage 2
//!     let channel: Channel = session.open_channel().unwrap();
//!     let mut shell = channel.open_shell().unwrap();
//!     run_shell(&mut shell);
//!     // Close channel.
//!     shell.close().unwrap();
//!     // Close session.
//!     session.close().unwrap();
//! }
//!
//! fn run_shell(shell: &mut ChannelShell) {
//!     sleep(Duration::from_millis(500));
//!     let vec = shell.read().unwrap();
//!     println!("{}", String::from_utf8(vec).unwrap());
//!
//!     shell.write(b"ls -all\n").unwrap();
//!
//!     sleep(Duration::from_millis(500));
//!
//!     let vec = shell.read().unwrap();
//!     println!("{}", String::from_utf8(vec).unwrap());
//! }
//! ```
//!
//! ### 3. scp
//!
//! ```rust
//! use ssh_rs::{Channel, ChannelScp, Session, ssh};
//!
//! fn main() {
//!     let mut session: Session = session();
//!     // Usage 1
//!     let scp: ChannelScp = session.open_scp().unwrap();
//!     scp.upload("local path", "remote path").unwrap();
//!
//!     let scp: ChannelScp = session.open_scp().unwrap();
//!     scp.download("local path", "remote path").unwrap();
//!
//!     // Usage 2
//!     let channel: Channel = session.open_channel().unwrap();
//!     let scp: ChannelScp = channel.open_scp().unwrap();
//!     scp.upload("local path", "remote path").unwrap();
//!
//!     let channel: Channel = session.open_channel().unwrap();
//!     let scp: ChannelScp = channel.open_scp().unwrap();
//!     scp.download("local path", "remote path").unwrap();
//!
//!     session.close().unwrap();
//! }
//!
//! ```



mod client;
mod client_r;
mod client_w;
mod session;
mod session_auth;
mod channel;
mod session_kex;
mod channel_shell;
mod channel_exec;
mod channel_scp;
mod channel_scp_d;
mod channel_scp_u;
mod config;
mod util;
mod window_size;
mod slog;
mod constant;
mod data;
mod packet;
mod algorithm;
mod user_info;
mod timeout;


pub mod key_pair;
pub mod error;
pub(crate) mod h;

pub use session::Session;
pub use channel::Channel;
pub use channel_shell::ChannelShell;
pub use channel_exec::ChannelExec;
pub use channel_scp::ChannelScp;
pub use user_info::UserInfo;


use crate::error::{SshError, SshResult};


pub mod ssh {
    use std::cell::{Cell, RefCell};
    use std::rc::Rc;
    use crate::h::H;
    use crate::Session;
    use crate::slog::Slog;

    pub fn create_session() -> Session {
        Session {
            timeout_sec: 30,
            h: Rc::new(RefCell::new(H::new())),
            config: None,
            client: None,
            encryption: None,
            key_exchange: None,
            public_key: None,
            is_encryption: Rc::new(Cell::new(false)),
            client_channel_no: 0,
        }
    }

    pub fn is_enable_log(b: bool) {
        if b {
            Slog::default()
        }
    }
}