Major refactor in files of the code™.
This commit is contained in:
parent
2bc046d7b6
commit
f877abacd6
@ -8,5 +8,3 @@ include = [ "lib/**/*.php" ]
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bincode = "1.3.1"
|
|
||||||
serde = { version = "1.0.63", features = [ "derive" ] }
|
|
||||||
|
28
src/constants.rs
Normal file
28
src/constants.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
pub const SSH_FXP_INIT: u8 = 1;
|
||||||
|
pub const SSH_FXP_VERSION: u8 = 2;
|
||||||
|
pub const SSH_FXP_OPEN: u8 = 3;
|
||||||
|
pub const SSH_FXP_CLOSE: u8 = 4;
|
||||||
|
pub const SSH_FXP_READ: u8 = 5;
|
||||||
|
pub const SSH_FXP_WRITE: u8 = 6;
|
||||||
|
pub const SSH_FXP_LSTAT: u8 = 7;
|
||||||
|
pub const SSH_FXP_FSTAT: u8 = 8;
|
||||||
|
pub const SSH_FXP_SETSTAT: u8 = 9;
|
||||||
|
pub const SSH_FXP_FSETSTAT: u8 = 10;
|
||||||
|
pub const SSH_FXP_OPENDIR: u8 = 11;
|
||||||
|
pub const SSH_FXP_READDIR: u8 = 12;
|
||||||
|
pub const SSH_FXP_REMOVE: u8 = 13;
|
||||||
|
pub const SSH_FXP_MKDIR: u8 = 14;
|
||||||
|
pub const SSH_FXP_RMDIR: u8 = 15;
|
||||||
|
pub const SSH_FXP_REALPATH: u8 = 16;
|
||||||
|
pub const SSH_FXP_STAT: u8 = 17;
|
||||||
|
pub const SSH_FXP_RENAME: u8 = 18;
|
||||||
|
pub const SSH_FXP_READLINK: u8 = 19;
|
||||||
|
pub const SSH_FXP_SYMLINK: u8 = 20;
|
||||||
|
pub const SSH_FXP_STATUS: u8 = 101;
|
||||||
|
pub const SSH_FXP_HANDLE: u8 = 102;
|
||||||
|
pub const SSH_FXP_DATA: u8 = 103;
|
||||||
|
pub const SSH_FXP_NAME: u8 = 104;
|
||||||
|
pub const SSH_FXP_ATTRS: u8 = 105;
|
||||||
|
pub const SSH_FXP_EXTENDED: u8 = 200;
|
||||||
|
pub const SSH_FXP_EXTENDED_REPLY: u8 = 201;
|
||||||
|
pub const NEXTCLOUD_PATH: &str = "/var/www/nextcloud.sergiotarxz.freemyip.com/htdocs/";
|
2
src/lib.rs
Normal file
2
src/lib.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
pub mod packet;
|
||||||
|
pub mod constants;
|
169
src/main.rs
169
src/main.rs
@ -1,41 +1,14 @@
|
|||||||
use std::convert::TryInto;
|
use fake_sftp::packet::Packet;
|
||||||
|
|
||||||
|
use fake_sftp::packet::dispatch_packet;
|
||||||
|
|
||||||
use std::io::{stdin, BufReader, BufWriter, Read, Write};
|
use std::io::{stdin, BufReader, BufWriter, Read, Write};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::vec::Vec;
|
|
||||||
|
|
||||||
const SSH_FXP_INIT: u8 = 1;
|
|
||||||
const SSH_FXP_VERSION: u8 = 2;
|
|
||||||
const SSH_FXP_OPEN: u8 = 3;
|
|
||||||
const SSH_FXP_CLOSE: u8 = 4;
|
|
||||||
const SSH_FXP_READ: u8 = 5;
|
|
||||||
const SSH_FXP_WRITE: u8 = 6;
|
|
||||||
const SSH_FXP_LSTAT: u8 = 7;
|
|
||||||
const SSH_FXP_FSTAT: u8 = 8;
|
|
||||||
const SSH_FXP_SETSTAT: u8 = 9;
|
|
||||||
const SSH_FXP_FSETSTAT: u8 = 10;
|
|
||||||
const SSH_FXP_OPENDIR: u8 = 11;
|
|
||||||
const SSH_FXP_READDIR: u8 = 12;
|
|
||||||
const SSH_FXP_REMOVE: u8 = 13;
|
|
||||||
const SSH_FXP_MKDIR: u8 = 14;
|
|
||||||
const SSH_FXP_RMDIR: u8 = 15;
|
|
||||||
const SSH_FXP_REALPATH: u8 = 16;
|
|
||||||
const SSH_FXP_STAT: u8 = 17;
|
|
||||||
const SSH_FXP_RENAME: u8 = 18;
|
|
||||||
const SSH_FXP_READLINK: u8 = 19;
|
|
||||||
const SSH_FXP_SYMLINK: u8 = 20;
|
|
||||||
const SSH_FXP_STATUS: u8 = 101;
|
|
||||||
const SSH_FXP_HANDLE: u8 = 102;
|
|
||||||
const SSH_FXP_DATA: u8 = 103;
|
|
||||||
const SSH_FXP_NAME: u8 = 104;
|
|
||||||
const SSH_FXP_ATTRS: u8 = 105;
|
|
||||||
const SSH_FXP_EXTENDED: u8 = 200;
|
|
||||||
const SSH_FXP_EXTENDED_REPLY: u8 = 201;
|
|
||||||
const NEXTCLOUD_PATH: &str = "/var/www/nextcloud.sergiotarxz.freemyip.com/htdocs/";
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
eprintln!("{}", execute_php("echo \"hola rusty mundo\";"));
|
eprintln!("{}", execute_php("echo \"hola rusty mundo\";"));
|
||||||
loop {
|
loop {
|
||||||
let packet = Packet::read_packet();
|
let packet = fake_sftp::packet::Packet::read_packet();
|
||||||
dispatch_packet(packet)
|
dispatch_packet(packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,135 +23,3 @@ fn execute_php(command: &str) -> String {
|
|||||||
buff_stderr.flush();
|
buff_stderr.flush();
|
||||||
return String::from_utf8(output.stdout).expect("Unable to parse php response");
|
return String::from_utf8(output.stdout).expect("Unable to parse php response");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dispatch_packet(packet: Packet) {
|
|
||||||
let mut buff_stdout = BufWriter::new(std::io::stdout());
|
|
||||||
if packet.packet_header.type_packet == SSH_FXP_INIT {
|
|
||||||
let init_packet_data: VersionPacketData = match VersionPacketData::deserialize(&packet.data)
|
|
||||||
{
|
|
||||||
Ok(ok) => ok,
|
|
||||||
Err(err) => panic!(err),
|
|
||||||
};
|
|
||||||
eprintln!("The client version is {}.", init_packet_data.version);
|
|
||||||
if init_packet_data.version < 3 {
|
|
||||||
panic!("Unsupported version, minimal client version 3.");
|
|
||||||
}
|
|
||||||
let version_packet_data = VersionPacketData {
|
|
||||||
version: 3,
|
|
||||||
extension_data: Vec::new(),
|
|
||||||
};
|
|
||||||
let mut response_packet = Packet {
|
|
||||||
packet_header: PacketHeader {
|
|
||||||
length: 0,
|
|
||||||
type_packet: SSH_FXP_VERSION,
|
|
||||||
},
|
|
||||||
data: version_packet_data.serialize(),
|
|
||||||
};
|
|
||||||
let serialized_response = response_packet.serialize();
|
|
||||||
eprintln!("{:#?}", serialized_response);
|
|
||||||
buff_stdout.write(&serialized_response);
|
|
||||||
buff_stdout.flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VersionPacketData {
|
|
||||||
fn deserialize(x: &[u8]) -> Result<VersionPacketData, std::string::String> {
|
|
||||||
if x.len() < 4 {
|
|
||||||
return Err("Error parsing version from init packet header.".to_string());
|
|
||||||
} else {
|
|
||||||
let mut u32_byte_array: [u8; 4] = [0; 4];
|
|
||||||
let mut extension_data = Vec::new();
|
|
||||||
u32_byte_array.copy_from_slice(&x[0..4]);
|
|
||||||
if x.len() > 4 {
|
|
||||||
extension_data.extend(&x[4..]);
|
|
||||||
}
|
|
||||||
return Ok(VersionPacketData {
|
|
||||||
version: u32::from_be_bytes(u32_byte_array),
|
|
||||||
extension_data: extension_data,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn serialize(&self) -> Vec<u8> {
|
|
||||||
let mut return_bytes = Vec::new();
|
|
||||||
let u32_byte_array: [u8; 4] = self.version.to_be_bytes();
|
|
||||||
return_bytes.extend(&u32_byte_array);
|
|
||||||
if self.extension_data.len() > 0 {
|
|
||||||
return_bytes.extend(&self.extension_data);
|
|
||||||
}
|
|
||||||
return_bytes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Packet {
|
|
||||||
fn read_packet() -> Packet {
|
|
||||||
let mut packet_header: [u8; 5] = [0; 5];
|
|
||||||
let mut buff_stdin = BufReader::new(std::io::stdin());
|
|
||||||
match buff_stdin.read(&mut packet_header) {
|
|
||||||
Ok(ok) => ok,
|
|
||||||
Err(err) => panic!("Could not fetch packet: {}", err),
|
|
||||||
};
|
|
||||||
eprintln!("{:#?}", packet_header);
|
|
||||||
let packet_header: PacketHeader = PacketHeader::deserialize(&packet_header);
|
|
||||||
eprintln!(
|
|
||||||
"Packet length {} and type {}.",
|
|
||||||
packet_header.length, packet_header.type_packet
|
|
||||||
);
|
|
||||||
let mut data: Vec<u8> = Vec::new();
|
|
||||||
data.resize(packet_header.length as usize - 1, 0);
|
|
||||||
match buff_stdin.read(&mut data) {
|
|
||||||
Ok(ok) => ok,
|
|
||||||
Err(err) => panic!("Could not fetch data: {}", err),
|
|
||||||
};
|
|
||||||
eprintln!("{:#?}", data);
|
|
||||||
Packet::deserialize(packet_header, data)
|
|
||||||
}
|
|
||||||
fn deserialize(packet_header: PacketHeader, data: Vec<u8>) -> Packet {
|
|
||||||
Packet {
|
|
||||||
packet_header: packet_header,
|
|
||||||
data: data,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn serialize(&mut self) -> Vec<u8> {
|
|
||||||
self.packet_header.length = (self.data.len() + 1) as u32;
|
|
||||||
let mut return_bytes = Vec::new();
|
|
||||||
return_bytes.extend(&self.packet_header.serialize());
|
|
||||||
return_bytes.extend(&self.data);
|
|
||||||
return_bytes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PacketHeader {
|
|
||||||
length: u32,
|
|
||||||
type_packet: u8,
|
|
||||||
}
|
|
||||||
impl PacketHeader {
|
|
||||||
fn deserialize(x: &[u8; 5]) -> PacketHeader {
|
|
||||||
let mut u32_byte_array: [u8; 4] = [0; 4];
|
|
||||||
u32_byte_array.copy_from_slice(&x[0..4]);
|
|
||||||
PacketHeader {
|
|
||||||
length: u32::from_be_bytes(u32_byte_array),
|
|
||||||
type_packet: x[4],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn serialize(&self) -> [u8; 5] {
|
|
||||||
let serializated_data: [u8; 5] = [0; 5];
|
|
||||||
let length = self.length.to_be_bytes();
|
|
||||||
let type_packet = self.type_packet;
|
|
||||||
let mut return_bytes = length.to_vec();
|
|
||||||
return_bytes.extend(&[type_packet][..]);
|
|
||||||
let boxed_return_bytes: Box<[u8; 5]> = return_bytes
|
|
||||||
.into_boxed_slice()
|
|
||||||
.try_into()
|
|
||||||
.expect("Unable to serialize.");
|
|
||||||
*boxed_return_bytes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Packet {
|
|
||||||
packet_header: PacketHeader,
|
|
||||||
data: Vec<u8>,
|
|
||||||
}
|
|
||||||
struct VersionPacketData {
|
|
||||||
version: u32,
|
|
||||||
extension_data: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
80
src/packet.rs
Normal file
80
src/packet.rs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
pub mod data;
|
||||||
|
pub mod header;
|
||||||
|
|
||||||
|
use crate::constants::SSH_FXP_INIT;
|
||||||
|
use crate::constants::SSH_FXP_VERSION;
|
||||||
|
|
||||||
|
use std::io::{BufReader, BufWriter, Read, Write};
|
||||||
|
|
||||||
|
pub fn dispatch_packet(packet: Packet) {
|
||||||
|
let mut buff_stdout = BufWriter::new(std::io::stdout());
|
||||||
|
if packet.packet_header.type_packet == SSH_FXP_INIT {
|
||||||
|
let init_packet_data: data::version::VersionData =
|
||||||
|
match data::version::VersionData::deserialize(&packet.data) {
|
||||||
|
Ok(ok) => ok,
|
||||||
|
Err(err) => panic!(err),
|
||||||
|
};
|
||||||
|
eprintln!("The client version is {}.", init_packet_data.version);
|
||||||
|
if init_packet_data.version < 3 {
|
||||||
|
panic!("Unsupported version, minimal client version 3.");
|
||||||
|
}
|
||||||
|
let version_packet_data = data::version::VersionData {
|
||||||
|
version: 3,
|
||||||
|
extension_data: Vec::new(),
|
||||||
|
};
|
||||||
|
let mut response_packet = Packet {
|
||||||
|
packet_header: header::PacketHeader {
|
||||||
|
length: 0,
|
||||||
|
type_packet: SSH_FXP_VERSION,
|
||||||
|
},
|
||||||
|
data: version_packet_data.serialize(),
|
||||||
|
};
|
||||||
|
let serialized_response = response_packet.serialize();
|
||||||
|
eprintln!("{:#?}", &serialized_response);
|
||||||
|
buff_stdout.write(&serialized_response);
|
||||||
|
buff_stdout.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Packet {
|
||||||
|
pub packet_header: header::PacketHeader,
|
||||||
|
pub data: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Packet {
|
||||||
|
pub fn read_packet() -> Packet {
|
||||||
|
let mut packet_header: [u8; 5] = [0; 5];
|
||||||
|
let mut buff_stdin = BufReader::new(std::io::stdin());
|
||||||
|
match buff_stdin.read(&mut packet_header) {
|
||||||
|
Ok(ok) => ok,
|
||||||
|
Err(err) => panic!("Could not fetch packet: {}", err),
|
||||||
|
};
|
||||||
|
eprintln!("{:#?}", packet_header);
|
||||||
|
let packet_header: header::PacketHeader = header::PacketHeader::deserialize(&packet_header);
|
||||||
|
eprintln!(
|
||||||
|
"Packet length {} and type {}.",
|
||||||
|
packet_header.length, packet_header.type_packet
|
||||||
|
);
|
||||||
|
let mut data: Vec<u8> = Vec::new();
|
||||||
|
data.resize(packet_header.length as usize - 1, 0);
|
||||||
|
match buff_stdin.read(&mut data) {
|
||||||
|
Ok(ok) => ok,
|
||||||
|
Err(err) => panic!("Could not fetch data: {}", err),
|
||||||
|
};
|
||||||
|
eprintln!("{:#?}", data);
|
||||||
|
Packet::deserialize(packet_header, data)
|
||||||
|
}
|
||||||
|
pub fn deserialize(packet_header: header::PacketHeader, data: Vec<u8>) -> Packet {
|
||||||
|
Packet {
|
||||||
|
packet_header: packet_header,
|
||||||
|
data: data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn serialize(&mut self) -> Vec<u8> {
|
||||||
|
self.packet_header.length = (self.data.len() + 1) as u32;
|
||||||
|
let mut return_bytes = Vec::new();
|
||||||
|
return_bytes.extend(&self.packet_header.serialize());
|
||||||
|
return_bytes.extend(&self.data);
|
||||||
|
return_bytes
|
||||||
|
}
|
||||||
|
}
|
1
src/packet/data.rs
Normal file
1
src/packet/data.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod version;
|
32
src/packet/data/version.rs
Normal file
32
src/packet/data/version.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
pub struct VersionData {
|
||||||
|
pub version: u32,
|
||||||
|
pub extension_data: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VersionData {
|
||||||
|
pub fn deserialize(x: &[u8]) -> Result<VersionData, std::string::String> {
|
||||||
|
if x.len() < 4 {
|
||||||
|
return Err("Error parsing version from init packet header.".to_string());
|
||||||
|
} else {
|
||||||
|
let mut u32_byte_array: [u8; 4] = [0; 4];
|
||||||
|
let mut extension_data = Vec::new();
|
||||||
|
u32_byte_array.copy_from_slice(&x[0..4]);
|
||||||
|
if x.len() > 4 {
|
||||||
|
extension_data.extend(&x[4..]);
|
||||||
|
}
|
||||||
|
return Ok(VersionData {
|
||||||
|
version: u32::from_be_bytes(u32_byte_array),
|
||||||
|
extension_data: extension_data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn serialize(&self) -> Vec<u8> {
|
||||||
|
let mut return_bytes = Vec::new();
|
||||||
|
let u32_byte_array: [u8; 4] = self.version.to_be_bytes();
|
||||||
|
return_bytes.extend(&u32_byte_array);
|
||||||
|
if self.extension_data.len() > 0 {
|
||||||
|
return_bytes.extend(&self.extension_data);
|
||||||
|
}
|
||||||
|
return_bytes
|
||||||
|
}
|
||||||
|
}
|
28
src/packet/header.rs
Normal file
28
src/packet/header.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use std::convert::TryInto;
|
||||||
|
pub struct PacketHeader {
|
||||||
|
pub length: u32,
|
||||||
|
pub type_packet: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PacketHeader {
|
||||||
|
pub fn deserialize(x: &[u8; 5]) -> PacketHeader {
|
||||||
|
let mut u32_byte_array: [u8; 4] = [0; 4];
|
||||||
|
u32_byte_array.copy_from_slice(&x[0..4]);
|
||||||
|
PacketHeader {
|
||||||
|
length: u32::from_be_bytes(u32_byte_array),
|
||||||
|
type_packet: x[4],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn serialize(&self) -> [u8; 5] {
|
||||||
|
let serializated_data: [u8; 5] = [0; 5];
|
||||||
|
let length = self.length.to_be_bytes();
|
||||||
|
let type_packet = self.type_packet;
|
||||||
|
let mut return_bytes = length.to_vec();
|
||||||
|
return_bytes.extend(&[type_packet][..]);
|
||||||
|
let boxed_return_bytes: Box<[u8; 5]> = return_bytes
|
||||||
|
.into_boxed_slice()
|
||||||
|
.try_into()
|
||||||
|
.expect("Unable to serialize.");
|
||||||
|
*boxed_return_bytes
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user