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
//! Dependencies
//! ```
//! ssh-rs = "*"
//! ```
//!
//! Quick example:
//!
//! shell
//! ```
//! use std::io::{stdin, stdout, Write};
//! use std::sync::{Arc, Mutex};
//! use std::{thread, time};
//! use ssh_rs::SSH;
//!
//! fn main() {
//!     let ssh = SSH::new();
//!     let mut session = ssh.get_session("192.168.3.101:22").unwrap();
//!     session.set_nonblocking(true).unwrap();
//!     session.set_user_and_password("root".to_string(), "123456".to_string());
//!     session.connect().unwrap();
//!     let mut channel = session.open_channel().unwrap();
//!     let mut shell = channel.open_shell().unwrap();
//!
//!     // thread::sleep(time::Duration::from_millis(500));
//!     // let result = shell.read().unwrap();
//!     // println!("{}", String::from_utf8(result).unwrap());
//!     // shell.close().unwrap();
//!     // session.close().unwrap();
//!
//!     let c1 = Arc::new(Mutex::new(shell));
//!     let c2 = Arc::clone(&c1);
//!     let t1 = thread::spawn(move || {
//!         loop {
//!             let mut x = c1.lock().unwrap().read().unwrap();
//!             if x.is_empty() { continue }
//!             stdout().write(x.as_slice()).unwrap();
//!             stdout().flush();
//!         }
//!     });
//!
//!     let t2 = thread::spawn(move || {
//!         loop {
//!             let mut cm = String::new();
//!             stdin().read_line(&mut cm).unwrap();
//!             c2.lock().unwrap().write(cm.as_bytes()).unwrap();
//!         }
//!     });
//!
//!     t1.join().unwrap();
//!     t2.join().unwrap();
//!
//! }
//! ```
//! #### exec
//! ```
//! use ssh_rs::SSH;
//!
//! fn main() {
//!     let ssh = SSH::new();
//!     let mut session = ssh.get_session("192.168.3.101:22").unwrap();
//!     session.set_user_and_password("root".to_string(), "123456".to_string());
//!     session.connect().unwrap();
//!     let mut channel = session.open_channel().unwrap();
//!     let mut exec = channel.open_exec().unwrap();
//!     let vec = exec.set_command("ps -ef |grep ssh").unwrap();
//!     println!("{}", String::from_utf8(vec).unwrap());
//!     session.close().unwrap();
//! }
//! ```




mod packet;
mod tcp;
mod algorithms;
mod encryption;
mod session;
mod hash;
mod channel;
mod key_agreement;
mod global_variable;
mod channel_shell;
mod channel_exec;

pub mod error;
pub use session::Session;
pub use channel::Channel;
pub use channel_shell::ChannelShell;
pub use channel_exec::ChannelExec;

use std::net::ToSocketAddrs;
use crate::error::SshError;
use crate::key_agreement::KeyAgreement;
use crate::session::Config;
use crate::tcp::Client;


pub struct SSH;

impl SSH {
    pub fn new() -> Self {
        Self
    }

    pub fn get_session<A: ToSocketAddrs>(self, adder: A) -> Result<Session, SshError> {
        Ok(Session {
            stream: Client::connect(adder)?,
            config: Config::new(),
            key_agreement: KeyAgreement::new()
        })
    }

}




#[allow(dead_code)]
pub mod strings {
    pub const CLIENT_VERSION: &'static str = "SSH-2.0-SSH_RS-0.1.0";
    pub const SSH_USERAUTH: &'static str = "ssh-userauth";
    pub const SSH_CONNECTION: &'static str = "ssh-connection";
    pub const PASSWORD: &'static str = "password";
    pub const SESSION: &'static str = "session";
    pub const SHELL: &'static str = "shell";
    pub const EXEC: &'static str = "exec";
    pub const PTY_REQ: &'static str = "pty-req";
    pub const XTERM_VAR: &'static str = "xterm-256color";
}

#[allow(dead_code)]
pub mod size {
    pub const ONE_GB: u32 = 1073741824;
    pub const BUF_SIZE: usize = 32768;
    pub const LOCAL_WINDOW_SIZE: u32 = 2097152;
}

#[allow(dead_code)]
pub mod message {
    pub const SSH_MSG_DISCONNECT: u8 = 1;
    pub const SSH_MSG_IGNORE: u8 = 2;
    pub const SSH_MSG_UNIMPLEMENTED: u8 = 3;
    pub const SSH_MSG_DEBUG: u8 = 4;
    pub const SSH_MSG_SERVICE_REQUEST: u8 = 5;
    pub const SSH_MSG_SERVICE_ACCEPT: u8 = 6;
    pub const SSH_MSG_KEXINIT: u8 = 20;
    pub const SSH_MSG_NEWKEYS: u8 = 21;
    pub const SSH_MSG_KEX_ECDH_INIT: u8 = 30;
    pub const SSH_MSG_KEX_ECDH_REPLY: u8 = 31;
    pub const SSH_MSG_USERAUTH_REQUEST: u8 = 50;
    pub const SSH_MSG_USERAUTH_FAILURE: u8 = 51;
    pub const SSH_MSG_USERAUTH_SUCCESS: u8 = 52;
    pub const SSH_MSG_GLOBAL_REQUEST: u8 = 80;
    pub const SSH_MSG_REQUEST_SUCCESS: u8 = 81;
    pub const SSH_MSG_REQUEST_FAILURE: u8 = 82;
    pub const SSH_MSG_CHANNEL_OPEN: u8 = 90;
    pub const SSH_MSG_CHANNEL_OPEN_CONFIRMATION: u8 = 91;
    pub const SSH_MSG_CHANNEL_OPEN_FAILURE: u8 = 92;
    pub const SSH_MSG_CHANNEL_WINDOW_ADJUST: u8 = 93;
    pub const SSH_MSG_CHANNEL_DATA: u8 = 94;
    pub const SSH_MSG_CHANNEL_EXTENDED_DATA: u8 = 95;
    pub const SSH_MSG_CHANNEL_EOF: u8 = 96;
    pub const SSH_MSG_CHANNEL_CLOSE: u8 = 97;
    pub const SSH_MSG_CHANNEL_REQUEST: u8 = 98;
    pub const SSH_MSG_CHANNEL_SUCCESS: u8 = 99;
    pub const SSH_MSG_CHANNEL_FAILURE: u8 = 100;
}


#[allow(dead_code)]
pub mod disconnection_message {
    pub const SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT: u8 = 1;
    pub const SSH_DISCONNECT_PROTOCOL_ERROR: u8 = 2;
    pub const SSH_DISCONNECT_KEY_EXCHANGE_FAILED: u8 = 3;
    pub const SSH_DISCONNECT_RESERVED: u8 = 4;
    pub const SSH_DISCONNECT_MAC_ERROR: u8 = 5;
    pub const SSH_DISCONNECT_COMPRESSION_ERROR: u8 = 6;
    pub const SSH_DISCONNECT_SERVICE_NOT_AVAILABLE: u8 = 7;
    pub const SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED: u8 = 8;
    pub const SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE: u8 = 9;
    pub const SSH_DISCONNECT_CONNECTION_LOST: u8 = 10;
    pub const SSH_DISCONNECT_BY_APPLICATION: u8 = 11;
    pub const SSH_DISCONNECT_TOO_MANY_CONNECTIONS: u8 = 12;
    pub const SSH_DISCONNECT_AUTH_CANCELLED_BY_USER: u8 = 13;
    pub const SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE: u8 = 14;
    pub const SSH_DISCONNECT_ILLEGAL_USER_NAME: u8 = 15;
}