mirror of
https://gitlab.redox-os.org/CoffeeCode/redox-ssh.git
synced 2025-12-28 15:02:18 +01:00
Resolve Clippy lints and run cargo fmt
This commit is contained in:
parent
8553d7011c
commit
c9d47981fb
20 changed files with 212 additions and 187 deletions
|
|
@ -1,10 +1,6 @@
|
||||||
chain_split_single_child = true
|
|
||||||
closure_block_indent_threshold = 1
|
|
||||||
fn_args_density = "Compressed"
|
|
||||||
wrap_comments = true
|
wrap_comments = true
|
||||||
control_brace_style = "ClosingNextLine"
|
control_brace_style = "ClosingNextLine"
|
||||||
max_width = 80
|
max_width = 80
|
||||||
reorder_imported_names = true
|
|
||||||
reorder_imports = true
|
reorder_imports = true
|
||||||
reorder_imports_in_group = true
|
|
||||||
use_try_shorthand = true
|
use_try_shorthand = true
|
||||||
|
|
@ -5,16 +5,15 @@ use crate::error::{ConnectionError, ConnectionResult};
|
||||||
use crate::key_exchange::{self, KeyExchange};
|
use crate::key_exchange::{self, KeyExchange};
|
||||||
|
|
||||||
/// Slice of implemented key exchange algorithms, ordered by preference
|
/// Slice of implemented key exchange algorithms, ordered by preference
|
||||||
pub static KEY_EXCHANGE: &[KeyExchangeAlgorithm] =
|
pub static KEY_EXCHANGE: &[KeyExchangeAlgorithm] = &[
|
||||||
&[
|
|
||||||
KeyExchangeAlgorithm::CURVE25519_SHA256,
|
KeyExchangeAlgorithm::CURVE25519_SHA256,
|
||||||
// KeyExchangeAlgorithm::DH_GROUP_EXCHANGE_SHA1,
|
// KeyExchangeAlgorithm::DH_GROUP_EXCHANGE_SHA1,
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Slice of implemented host key algorithms, ordered by preference
|
/// Slice of implemented host key algorithms, ordered by preference
|
||||||
pub static HOST_KEY: &[PublicKeyAlgorithm] = &[
|
pub static HOST_KEY: &[PublicKeyAlgorithm] = &[
|
||||||
PublicKeyAlgorithm::SSH_ED25519,
|
PublicKeyAlgorithm::SSH_ED25519,
|
||||||
// PublicKeyAlgorithm::SSH_RSA,
|
// PublicKeyAlgorithm::SSH_RSA,
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Slice of implemented encryption algorithms, ordered by preference
|
/// Slice of implemented encryption algorithms, ordered by preference
|
||||||
|
|
@ -29,8 +28,10 @@ pub static COMPRESSION: &[CompressionAlgorithm] =
|
||||||
&[CompressionAlgorithm::None, CompressionAlgorithm::Zlib];
|
&[CompressionAlgorithm::None, CompressionAlgorithm::Zlib];
|
||||||
|
|
||||||
/// Find the best matching algorithm
|
/// Find the best matching algorithm
|
||||||
pub fn negotiate<A: PartialEq + Copy>(server: &[A], client: &[A])
|
pub fn negotiate<A: PartialEq + Copy>(
|
||||||
-> ConnectionResult<A> {
|
server: &[A],
|
||||||
|
client: &[A],
|
||||||
|
) -> ConnectionResult<A> {
|
||||||
for algorithm in client.iter() {
|
for algorithm in client.iter() {
|
||||||
if server.iter().any(|a| a == algorithm) {
|
if server.iter().any(|a| a == algorithm) {
|
||||||
return Ok(*algorithm);
|
return Ok(*algorithm);
|
||||||
|
|
@ -59,11 +60,10 @@ pub enum KeyExchangeAlgorithm {
|
||||||
impl KeyExchangeAlgorithm {
|
impl KeyExchangeAlgorithm {
|
||||||
pub fn instance(&self) -> Option<Box<dyn KeyExchange>> {
|
pub fn instance(&self) -> Option<Box<dyn KeyExchange>> {
|
||||||
use self::KeyExchangeAlgorithm::*;
|
use self::KeyExchangeAlgorithm::*;
|
||||||
match self
|
match self {
|
||||||
{
|
&CURVE25519_SHA256 => {
|
||||||
&CURVE25519_SHA256 => Some(
|
Some(Box::new(key_exchange::Curve25519::new()))
|
||||||
Box::new(key_exchange::Curve25519::new()),
|
}
|
||||||
),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -73,15 +73,14 @@ impl FromStr for KeyExchangeAlgorithm {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<KeyExchangeAlgorithm, ()> {
|
fn from_str(s: &str) -> Result<KeyExchangeAlgorithm, ()> {
|
||||||
use self::KeyExchangeAlgorithm::*;
|
use self::KeyExchangeAlgorithm::*;
|
||||||
match s
|
match s {
|
||||||
{
|
|
||||||
"curve25519-sha256" => Ok(CURVE25519_SHA256),
|
"curve25519-sha256" => Ok(CURVE25519_SHA256),
|
||||||
"ecdh-sha2-nistp256" => Ok(ECDH_SHA2_NISTP256),
|
"ecdh-sha2-nistp256" => Ok(ECDH_SHA2_NISTP256),
|
||||||
"ecdh-sha2-nistp384" => Ok(ECDH_SHA2_NISTP384),
|
"ecdh-sha2-nistp384" => Ok(ECDH_SHA2_NISTP384),
|
||||||
"ecdh-sha2-nistp521" => Ok(ECDH_SHA2_NISTP521),
|
"ecdh-sha2-nistp521" => Ok(ECDH_SHA2_NISTP521),
|
||||||
"diffie-hellman-group-exchange-sha256" => Ok(
|
"diffie-hellman-group-exchange-sha256" => {
|
||||||
DH_GROUP_EXCHANGE_SHA256,
|
Ok(DH_GROUP_EXCHANGE_SHA256)
|
||||||
),
|
}
|
||||||
"diffie-hellman-group-exchange-sha1" => Ok(DH_GROUP_EXCHANGE_SHA1),
|
"diffie-hellman-group-exchange-sha1" => Ok(DH_GROUP_EXCHANGE_SHA1),
|
||||||
"diffie-hellman-group16-sha512" => Ok(DH_GROUP16_SHA512),
|
"diffie-hellman-group16-sha512" => Ok(DH_GROUP16_SHA512),
|
||||||
"diffie-hellman-group18-sha512" => Ok(DH_GROUP18_SHA512),
|
"diffie-hellman-group18-sha512" => Ok(DH_GROUP18_SHA512),
|
||||||
|
|
@ -99,8 +98,7 @@ impl FromStr for KeyExchangeAlgorithm {
|
||||||
impl fmt::Display for KeyExchangeAlgorithm {
|
impl fmt::Display for KeyExchangeAlgorithm {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
use self::KeyExchangeAlgorithm::*;
|
use self::KeyExchangeAlgorithm::*;
|
||||||
f.write_str(match *self
|
f.write_str(match *self {
|
||||||
{
|
|
||||||
CURVE25519_SHA256 => "curve25519-sha256",
|
CURVE25519_SHA256 => "curve25519-sha256",
|
||||||
ECDH_SHA2_NISTP256 => "ecdh-sha2-nistp256",
|
ECDH_SHA2_NISTP256 => "ecdh-sha2-nistp256",
|
||||||
ECDH_SHA2_NISTP384 => "ecdh-sha2-nistp384",
|
ECDH_SHA2_NISTP384 => "ecdh-sha2-nistp384",
|
||||||
|
|
@ -132,8 +130,7 @@ impl FromStr for PublicKeyAlgorithm {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<PublicKeyAlgorithm, ()> {
|
fn from_str(s: &str) -> Result<PublicKeyAlgorithm, ()> {
|
||||||
use self::PublicKeyAlgorithm::*;
|
use self::PublicKeyAlgorithm::*;
|
||||||
match s
|
match s {
|
||||||
{
|
|
||||||
"ssh-rsa" => Ok(SSH_RSA),
|
"ssh-rsa" => Ok(SSH_RSA),
|
||||||
"rsa-sha2-256" => Ok(RSA_SHA2_256),
|
"rsa-sha2-256" => Ok(RSA_SHA2_256),
|
||||||
"rsa-sha2-512" => Ok(RSA_SHA2_512),
|
"rsa-sha2-512" => Ok(RSA_SHA2_512),
|
||||||
|
|
@ -152,8 +149,7 @@ impl FromStr for PublicKeyAlgorithm {
|
||||||
impl fmt::Display for PublicKeyAlgorithm {
|
impl fmt::Display for PublicKeyAlgorithm {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
use self::PublicKeyAlgorithm::*;
|
use self::PublicKeyAlgorithm::*;
|
||||||
f.write_str(match *self
|
f.write_str(match *self {
|
||||||
{
|
|
||||||
SSH_RSA => "ssh-rsa",
|
SSH_RSA => "ssh-rsa",
|
||||||
RSA_SHA2_256 => "rsa-sha2-256",
|
RSA_SHA2_256 => "rsa-sha2-256",
|
||||||
RSA_SHA2_512 => "rsa-sha2-512",
|
RSA_SHA2_512 => "rsa-sha2-512",
|
||||||
|
|
@ -181,8 +177,7 @@ impl FromStr for EncryptionAlgorithm {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<EncryptionAlgorithm, ()> {
|
fn from_str(s: &str) -> Result<EncryptionAlgorithm, ()> {
|
||||||
use self::EncryptionAlgorithm::*;
|
use self::EncryptionAlgorithm::*;
|
||||||
match s
|
match s {
|
||||||
{
|
|
||||||
"aes128-ctr" => Ok(AES128_CTR),
|
"aes128-ctr" => Ok(AES128_CTR),
|
||||||
"aes128-cbc" => Ok(AES128_CBC),
|
"aes128-cbc" => Ok(AES128_CBC),
|
||||||
"aes192-ctr" => Ok(AES192_CTR),
|
"aes192-ctr" => Ok(AES192_CTR),
|
||||||
|
|
@ -201,8 +196,7 @@ impl FromStr for EncryptionAlgorithm {
|
||||||
impl fmt::Display for EncryptionAlgorithm {
|
impl fmt::Display for EncryptionAlgorithm {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
use self::EncryptionAlgorithm::*;
|
use self::EncryptionAlgorithm::*;
|
||||||
f.write_str(match *self
|
f.write_str(match *self {
|
||||||
{
|
|
||||||
AES128_CTR => "aes128-ctr",
|
AES128_CTR => "aes128-ctr",
|
||||||
AES128_CBC => "aes128-cbc",
|
AES128_CBC => "aes128-cbc",
|
||||||
AES192_CTR => "aes192-ctr",
|
AES192_CTR => "aes192-ctr",
|
||||||
|
|
@ -227,8 +221,7 @@ impl FromStr for MacAlgorithm {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<MacAlgorithm, ()> {
|
fn from_str(s: &str) -> Result<MacAlgorithm, ()> {
|
||||||
use self::MacAlgorithm::*;
|
use self::MacAlgorithm::*;
|
||||||
match s
|
match s {
|
||||||
{
|
|
||||||
"hmac-sha1" => Ok(HMAC_SHA1),
|
"hmac-sha1" => Ok(HMAC_SHA1),
|
||||||
"hmac-sha2-256" => Ok(HMAC_SHA2_256),
|
"hmac-sha2-256" => Ok(HMAC_SHA2_256),
|
||||||
"hmac-sha2-512" => Ok(HMAC_SHA2_512),
|
"hmac-sha2-512" => Ok(HMAC_SHA2_512),
|
||||||
|
|
@ -244,8 +237,7 @@ impl FromStr for MacAlgorithm {
|
||||||
impl fmt::Display for MacAlgorithm {
|
impl fmt::Display for MacAlgorithm {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
use self::MacAlgorithm::*;
|
use self::MacAlgorithm::*;
|
||||||
f.write_str(match *self
|
f.write_str(match *self {
|
||||||
{
|
|
||||||
HMAC_SHA1 => "hmac-sha1",
|
HMAC_SHA1 => "hmac-sha1",
|
||||||
HMAC_SHA2_256 => "hmac-sha2-256",
|
HMAC_SHA2_256 => "hmac-sha2-256",
|
||||||
HMAC_SHA2_512 => "hmac-sha2-512",
|
HMAC_SHA2_512 => "hmac-sha2-512",
|
||||||
|
|
@ -263,8 +255,7 @@ pub enum CompressionAlgorithm {
|
||||||
impl FromStr for CompressionAlgorithm {
|
impl FromStr for CompressionAlgorithm {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<CompressionAlgorithm, ()> {
|
fn from_str(s: &str) -> Result<CompressionAlgorithm, ()> {
|
||||||
match s
|
match s {
|
||||||
{
|
|
||||||
"zlib" => Ok(CompressionAlgorithm::Zlib),
|
"zlib" => Ok(CompressionAlgorithm::Zlib),
|
||||||
"none" => Ok(CompressionAlgorithm::None),
|
"none" => Ok(CompressionAlgorithm::None),
|
||||||
_ => {
|
_ => {
|
||||||
|
|
@ -277,8 +268,7 @@ impl FromStr for CompressionAlgorithm {
|
||||||
|
|
||||||
impl fmt::Display for CompressionAlgorithm {
|
impl fmt::Display for CompressionAlgorithm {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.write_str(match *self
|
f.write_str(match *self {
|
||||||
{
|
|
||||||
CompressionAlgorithm::Zlib => "zlib",
|
CompressionAlgorithm::Zlib => "zlib",
|
||||||
CompressionAlgorithm::None => "none",
|
CompressionAlgorithm::None => "none",
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
extern crate ssh;
|
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
extern crate ssh;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
|
@ -8,8 +8,8 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use log::{LevelFilter, Metadata, Record};
|
use log::{LevelFilter, Metadata, Record};
|
||||||
|
|
||||||
use ssh::{Server, ServerConfig};
|
|
||||||
use ssh::public_key::ED25519;
|
use ssh::public_key::ED25519;
|
||||||
|
use ssh::{Server, ServerConfig};
|
||||||
|
|
||||||
struct StdErrLogger;
|
struct StdErrLogger;
|
||||||
|
|
||||||
|
|
@ -33,9 +33,8 @@ pub fn main() {
|
||||||
let mut verbosity = LevelFilter::Warn;
|
let mut verbosity = LevelFilter::Warn;
|
||||||
let mut foreground = false;
|
let mut foreground = false;
|
||||||
|
|
||||||
let key_pair = File::open("server.key").and_then(
|
let key_pair =
|
||||||
|mut f| (ED25519.import)(&mut f),
|
File::open("server.key").and_then(|mut f| (ED25519.import)(&mut f));
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(ref err) = key_pair.as_ref().err() {
|
if let Some(ref err) = key_pair.as_ref().err() {
|
||||||
eprintln!("sshd: failed to open server.key: {}", err);
|
eprintln!("sshd: failed to open server.key: {}", err);
|
||||||
|
|
@ -50,17 +49,16 @@ pub fn main() {
|
||||||
|
|
||||||
let mut args = env::args().skip(1);
|
let mut args = env::args().skip(1);
|
||||||
while let Some(arg) = args.next() {
|
while let Some(arg) = args.next() {
|
||||||
match arg.as_ref()
|
match arg.as_ref() {
|
||||||
{
|
|
||||||
"-v" => verbosity = LevelFilter::Info,
|
"-v" => verbosity = LevelFilter::Info,
|
||||||
"-vv" => verbosity = LevelFilter::Debug,
|
"-vv" => verbosity = LevelFilter::Debug,
|
||||||
"-vvv" => verbosity = LevelFilter::Trace,
|
"-vvv" => verbosity = LevelFilter::Trace,
|
||||||
"-f" => foreground = true,
|
"-f" => foreground = true,
|
||||||
"-p" => {
|
"-p" => {
|
||||||
config.port =
|
config.port = u16::from_str(
|
||||||
u16::from_str(
|
&args.next().expect("sshd: no argument to -p option"),
|
||||||
&args.next().expect("sshd: no argument to -p option"),
|
)
|
||||||
).expect("sshd: invalid port number to -p option");
|
.expect("sshd: invalid port number to -p option");
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,8 +114,7 @@ impl Channel {
|
||||||
/// Reads data **from** this channel and writes it **to** the buffer/.
|
/// Reads data **from** this channel and writes it **to** the buffer/.
|
||||||
pub fn read_stdout(&mut self, buf: &mut String) -> io::Result<usize> {
|
pub fn read_stdout(&mut self, buf: &mut String) -> io::Result<usize> {
|
||||||
if let Some(pipes) = &mut self.pipes {
|
if let Some(pipes) = &mut self.pipes {
|
||||||
let res_len = pipes.stdout.read_line(buf);
|
pipes.stdout.read_line(buf)
|
||||||
res_len
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Ok(0)
|
Ok(0)
|
||||||
|
|
@ -124,8 +123,7 @@ impl Channel {
|
||||||
|
|
||||||
pub fn read_stderr(&mut self, buf: &mut String) -> io::Result<usize> {
|
pub fn read_stderr(&mut self, buf: &mut String) -> io::Result<usize> {
|
||||||
if let Some(pipes) = &mut self.pipes {
|
if let Some(pipes) = &mut self.pipes {
|
||||||
let res_len = pipes.stderr.read_line(buf);
|
pipes.stderr.read_line(buf)
|
||||||
res_len
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Ok(0)
|
Ok(0)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
use std::{fs::File, io::{Read, Write}, os::fd::FromRawFd, thread};
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
io::{Read, Write},
|
||||||
|
os::fd::FromRawFd,
|
||||||
|
thread,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
|
|
||||||
|
|
@ -53,7 +58,7 @@ impl Channel {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Error occured, ignoring: {}", e);
|
warn!("Error occured, ignoring: {}", e);
|
||||||
1 // TODO
|
1 // TODO
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is weird.
|
// This is weird.
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
use std::{
|
use std::{
|
||||||
fs::OpenOptions, io::{stdin, BufReader}, os::{
|
fs::OpenOptions,
|
||||||
|
io::{stdin, BufReader},
|
||||||
|
os::{
|
||||||
fd::{FromRawFd, IntoRawFd, RawFd},
|
fd::{FromRawFd, IntoRawFd, RawFd},
|
||||||
unix::process::CommandExt,
|
unix::process::CommandExt,
|
||||||
}, path::PathBuf, process::{self, ChildStderr, ChildStdin, ChildStdout, Stdio}
|
},
|
||||||
|
path::PathBuf,
|
||||||
|
process::{self, ChildStderr, ChildStdin, ChildStdout, Stdio},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::sys;
|
use crate::sys;
|
||||||
|
|
@ -27,7 +31,7 @@ impl Channel {
|
||||||
non_blockify_reader(pipes.stdout.get_ref());
|
non_blockify_reader(pipes.stdout.get_ref());
|
||||||
non_blockify_reader(pipes.stderr.get_ref());
|
non_blockify_reader(pipes.stderr.get_ref());
|
||||||
self.pipes = Some(pipes);
|
self.pipes = Some(pipes);
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,6 +76,8 @@ fn with_tty(tty_path: &PathBuf) {
|
||||||
}
|
}
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// TODO: TTY is broken
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_tty(tty_path: &PathBuf, read: bool, write: bool) -> RawFd {
|
fn open_tty(tty_path: &PathBuf, read: bool, write: bool) -> RawFd {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::collections::{BTreeMap, VecDeque};
|
use std::collections::{BTreeMap, VecDeque};
|
||||||
use std::io::{self, BufReader, Read, Write};
|
use std::io::{self, BufReader, Read, Write};
|
||||||
|
use std::os::fd::AsRawFd;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use rand::distributions::Standard;
|
use rand::distributions::Standard;
|
||||||
|
|
@ -62,7 +63,10 @@ impl Connection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run<S: Read + Write + std::os::fd::AsRawFd>(&mut self, stream: &mut S) -> Result<()> {
|
pub fn run<S: Read + Write + AsRawFd>(
|
||||||
|
&mut self,
|
||||||
|
stream: &mut S,
|
||||||
|
) -> Result<()> {
|
||||||
self.send_id(stream)?;
|
self.send_id(stream)?;
|
||||||
self.read_id(stream)?;
|
self.read_id(stream)?;
|
||||||
|
|
||||||
|
|
@ -73,7 +77,11 @@ impl Connection {
|
||||||
std::thread::sleep(std::time::Duration::from_millis(1)); // TODO: REMOVE: debugging
|
std::thread::sleep(std::time::Duration::from_millis(1)); // TODO: REMOVE: debugging
|
||||||
let response = match self.recv(&mut reader) {
|
let response = match self.recv(&mut reader) {
|
||||||
Ok(packet) => self.process_packet(packet)?,
|
Ok(packet) => self.process_packet(packet)?,
|
||||||
Err(ConnectionError::Io(ref io_err)) if io_err.kind() == io::ErrorKind::WouldBlock => None,
|
Err(ConnectionError::Io(ref io_err))
|
||||||
|
if io_err.kind() == io::ErrorKind::WouldBlock =>
|
||||||
|
{
|
||||||
|
None
|
||||||
|
}
|
||||||
Err(err) => return Err(err),
|
Err(err) => return Err(err),
|
||||||
};
|
};
|
||||||
// let response = self.process_packet(packet)?;
|
// let response = self.process_packet(packet)?;
|
||||||
|
|
@ -91,7 +99,11 @@ impl Connection {
|
||||||
// TODO: Consider pushing to `tx_queue`?
|
// TODO: Consider pushing to `tx_queue`?
|
||||||
for (_, channel) in self.channels.iter_mut() {
|
for (_, channel) in self.channels.iter_mut() {
|
||||||
let mut buf = String::with_capacity(1024);
|
let mut buf = String::with_capacity(1024);
|
||||||
if channel.read_pty_master(unsafe { buf.as_mut_vec() }).unwrap_or(0) != 0 {
|
if channel
|
||||||
|
.read_pty_master(unsafe { buf.as_mut_vec() })
|
||||||
|
.unwrap_or(0)
|
||||||
|
!= 0
|
||||||
|
{
|
||||||
let mut packet = Packet::new(MessageType::ChannelData);
|
let mut packet = Packet::new(MessageType::ChannelData);
|
||||||
packet.write_uint32(channel.id())?;
|
packet.write_uint32(channel.id())?;
|
||||||
packet.write_string(&buf)?;
|
packet.write_string(&buf)?;
|
||||||
|
|
@ -105,7 +117,8 @@ impl Connection {
|
||||||
packets.push(packet)
|
packets.push(packet)
|
||||||
}
|
}
|
||||||
if channel.read_stderr(&mut buf).unwrap_or(0) != 0 {
|
if channel.read_stderr(&mut buf).unwrap_or(0) != 0 {
|
||||||
let mut packet = Packet::new(MessageType::ChannelExtendedData);
|
let mut packet =
|
||||||
|
Packet::new(MessageType::ChannelExtendedData);
|
||||||
packet.write_uint32(channel.id())?;
|
packet.write_uint32(channel.id())?;
|
||||||
packet.write_uint32(1)?; // Data Type Code for stderr
|
packet.write_uint32(1)?; // Data Type Code for stderr
|
||||||
packet.write_string(&buf)?;
|
packet.write_string(&buf)?;
|
||||||
|
|
@ -123,7 +136,8 @@ impl Connection {
|
||||||
let packet = if let Some((ref mut c2s, _)) = self.encryption {
|
let packet = if let Some((ref mut c2s, _)) = self.encryption {
|
||||||
let mut decryptor = Decryptor::new(&mut **c2s, &mut stream);
|
let mut decryptor = Decryptor::new(&mut **c2s, &mut stream);
|
||||||
Packet::read_from(&mut decryptor)
|
Packet::read_from(&mut decryptor)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Packet::read_from(&mut stream)
|
Packet::read_from(&mut stream)
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
|
@ -147,8 +161,11 @@ impl Connection {
|
||||||
Ok(packet)
|
Ok(packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send(&mut self, mut stream: &mut dyn Write, packet: Packet)
|
fn send(
|
||||||
-> io::Result<()> {
|
&mut self,
|
||||||
|
mut stream: &mut dyn Write,
|
||||||
|
packet: Packet,
|
||||||
|
) -> io::Result<()> {
|
||||||
debug!("Sending packet {}: {:?}", self.seq.1, packet);
|
debug!("Sending packet {}: {:?}", self.seq.1, packet);
|
||||||
|
|
||||||
let packet = packet.into_raw()?;
|
let packet = packet.into_raw()?;
|
||||||
|
|
@ -202,7 +219,8 @@ impl Connection {
|
||||||
info!("Peer identifies as {:?}", id);
|
info!("Peer identifies as {:?}", id);
|
||||||
self.hash_data.client_id = Some(id.to_owned());
|
self.hash_data.client_id = Some(id.to_owned());
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Err(io::Error::new(io::ErrorKind::InvalidData, "invalid id"))
|
Err(io::Error::new(io::ErrorKind::InvalidData, "invalid id"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -212,17 +230,12 @@ impl Connection {
|
||||||
|
|
||||||
let kex = self.key_exchange.take().ok_or(KeyGeneration)?;
|
let kex = self.key_exchange.take().ok_or(KeyGeneration)?;
|
||||||
|
|
||||||
let key = kex.hash(
|
let key = kex.hash(&[
|
||||||
&[
|
kex.shared_secret().ok_or(KeyGeneration)?,
|
||||||
kex.shared_secret().ok_or(KeyGeneration)?,
|
kex.exchange_hash().ok_or(KeyGeneration)?,
|
||||||
kex.exchange_hash().ok_or(KeyGeneration)?,
|
id,
|
||||||
id,
|
self.session_id.as_ref().ok_or(KeyGeneration)?.as_slice(),
|
||||||
self.session_id
|
]);
|
||||||
.as_ref()
|
|
||||||
.ok_or(KeyGeneration)?
|
|
||||||
.as_slice(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
self.key_exchange = Some(kex);
|
self.key_exchange = Some(kex);
|
||||||
|
|
||||||
|
|
@ -256,11 +269,10 @@ impl Connection {
|
||||||
let mac_c2s = self.generate_key(b"E", 256)?;
|
let mac_c2s = self.generate_key(b"E", 256)?;
|
||||||
let mac_s2c = self.generate_key(b"F", 256)?;
|
let mac_s2c = self.generate_key(b"F", 256)?;
|
||||||
|
|
||||||
self.encryption =
|
self.encryption = Some((
|
||||||
Some((
|
Box::new(AesCtr::new(enc_c2s.as_slice(), iv_c2s.as_slice())),
|
||||||
Box::new(AesCtr::new(enc_c2s.as_slice(), iv_c2s.as_slice())),
|
Box::new(AesCtr::new(enc_s2c.as_slice(), iv_s2c.as_slice())),
|
||||||
Box::new(AesCtr::new(enc_s2c.as_slice(), iv_s2c.as_slice())),
|
));
|
||||||
));
|
|
||||||
|
|
||||||
self.mac = Some((
|
self.mac = Some((
|
||||||
Box::new(Hmac::new(mac_c2s.as_slice())),
|
Box::new(Hmac::new(mac_c2s.as_slice())),
|
||||||
|
|
@ -295,7 +307,8 @@ impl Connection {
|
||||||
assert!(!(reader.read_bool()?));
|
assert!(!(reader.read_bool()?));
|
||||||
let pass = reader.read_utf8()?;
|
let pass = reader.read_utf8()?;
|
||||||
pass == "hunter2"
|
pass == "hunter2"
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -303,7 +316,8 @@ impl Connection {
|
||||||
|
|
||||||
if success {
|
if success {
|
||||||
Ok(Some(Packet::new(MessageType::UserAuthSuccess)))
|
Ok(Some(Packet::new(MessageType::UserAuthSuccess)))
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
let mut res = Packet::new(MessageType::UserAuthFailure);
|
let mut res = Packet::new(MessageType::UserAuthFailure);
|
||||||
res.write_string("password")?;
|
res.write_string("password")?;
|
||||||
res.write_bool(false)?;
|
res.write_bool(false)?;
|
||||||
|
|
@ -321,7 +335,8 @@ impl Connection {
|
||||||
|
|
||||||
let id = if let Some((id, chan)) = self.channels.iter().next_back() {
|
let id = if let Some((id, chan)) = self.channels.iter().next_back() {
|
||||||
id + 1
|
id + 1
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -357,17 +372,20 @@ impl Connection {
|
||||||
})),
|
})),
|
||||||
"shell" => Some(ChannelRequest::Shell),
|
"shell" => Some(ChannelRequest::Shell),
|
||||||
"env" => Some(ChannelRequest::Env(
|
"env" => Some(ChannelRequest::Env(
|
||||||
String::from_utf8(reader.read_string()?).unwrap(), // TODO: error handling
|
String::from_utf8(reader.read_string()?).unwrap(), /* TODO: error handling */
|
||||||
|
String::from_utf8(reader.read_string()?).unwrap(),
|
||||||
|
)),
|
||||||
|
"exec" => Some(ChannelRequest::Exec(
|
||||||
String::from_utf8(reader.read_string()?).unwrap(),
|
String::from_utf8(reader.read_string()?).unwrap(),
|
||||||
)),
|
)),
|
||||||
"exec" => Some(ChannelRequest::Exec(String::from_utf8(reader.read_string()?).unwrap())),
|
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(request) = request {
|
if let Some(request) = request {
|
||||||
let channel = self.channels.get_mut(&channel_id).unwrap();
|
let channel = self.channels.get_mut(&channel_id).unwrap();
|
||||||
channel.handle_request(request);
|
channel.handle_request(request);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
warn!("Unkown channel request {}", name);
|
warn!("Unkown channel request {}", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -375,7 +393,8 @@ impl Connection {
|
||||||
let mut res = Packet::new(MessageType::ChannelSuccess);
|
let mut res = Packet::new(MessageType::ChannelSuccess);
|
||||||
res.write_uint32(0)?;
|
res.write_uint32(0)?;
|
||||||
Ok(Some(res))
|
Ok(Some(res))
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,11 @@ pub struct AesCtr {
|
||||||
|
|
||||||
impl AesCtr {
|
impl AesCtr {
|
||||||
pub fn new(key: &[u8], iv: &[u8]) -> Self {
|
pub fn new(key: &[u8], iv: &[u8]) -> Self {
|
||||||
let key: [u8; 32] = key.try_into().expect("slice with incorrect length");
|
let key: [u8; 32] =
|
||||||
|
key.try_into().expect("slice with incorrect length");
|
||||||
let key = GenericArray::from_slice(&key);
|
let key = GenericArray::from_slice(&key);
|
||||||
let iv: [u8; 16] = iv[..16].try_into().expect("slice with incorrect length");
|
let iv: [u8; 16] =
|
||||||
|
iv[..16].try_into().expect("slice with incorrect length");
|
||||||
let iv = GenericArray::from_slice(&iv);
|
let iv = GenericArray::from_slice(&iv);
|
||||||
let cipher = ThisCipher::new(key, iv);
|
let cipher = ThisCipher::new(key, iv);
|
||||||
Self { cipher }
|
Self { cipher }
|
||||||
|
|
|
||||||
|
|
@ -17,23 +17,20 @@ pub struct Decryptor<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Decryptor<'a> {
|
impl<'a> Decryptor<'a> {
|
||||||
pub fn new(encryption: &'a mut dyn Encryption, stream: &'a mut dyn Read)
|
pub fn new(
|
||||||
-> Decryptor<'a> {
|
encryption: &'a mut dyn Encryption,
|
||||||
Decryptor {
|
stream: &'a mut dyn Read,
|
||||||
encryption,
|
) -> Decryptor<'a> {
|
||||||
stream,
|
Decryptor { encryption, stream }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Read for Decryptor<'a> {
|
impl Read for Decryptor<'_> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
let mut tmp = vec![0; buf.len()];
|
let mut tmp = vec![0; buf.len()];
|
||||||
let count = self.stream.read(tmp.as_mut_slice())?;
|
let count = self.stream.read(tmp.as_mut_slice())?;
|
||||||
self.encryption.decrypt(
|
self.encryption
|
||||||
&tmp.as_slice()[0..count],
|
.decrypt(&tmp.as_slice()[0..count], &mut buf[0..count]);
|
||||||
&mut buf[0..count],
|
|
||||||
);
|
|
||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
21
src/error.rs
21
src/error.rs
|
|
@ -16,15 +16,18 @@ pub enum ConnectionError {
|
||||||
impl fmt::Display for ConnectionError {
|
impl fmt::Display for ConnectionError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
use self::ConnectionError::*;
|
use self::ConnectionError::*;
|
||||||
write!(f, "connection error: {}", (match &self
|
write!(
|
||||||
{
|
f,
|
||||||
Io(err) => format!("io error: {}", err),
|
"connection error: {}",
|
||||||
Protocol => "protocol error".to_owned(),
|
(match &self {
|
||||||
Negotiation => "negotiation error".to_owned(),
|
Io(err) => format!("io error: {}", err),
|
||||||
KeyExchange => "key exchange error".to_owned(),
|
Protocol => "protocol error".to_owned(),
|
||||||
KeyGeneration => "key generation error".to_owned(),
|
Negotiation => "negotiation error".to_owned(),
|
||||||
Integrity => "integrity error".to_owned(),
|
KeyExchange => "key exchange error".to_owned(),
|
||||||
}))
|
KeyGeneration => "key generation error".to_owned(),
|
||||||
|
Integrity => "integrity error".to_owned(),
|
||||||
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,14 +50,12 @@ impl KeyExchange for Curve25519 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(&mut self, conn: &mut Connection, packet: Packet) -> KexResult {
|
fn process(&mut self, conn: &mut Connection, packet: Packet) -> KexResult {
|
||||||
match packet.msg_type()
|
match packet.msg_type() {
|
||||||
{
|
|
||||||
MessageType::KeyExchange(ECDH_KEX_INIT) => {
|
MessageType::KeyExchange(ECDH_KEX_INIT) => {
|
||||||
let mut reader = packet.reader();
|
let mut reader = packet.reader();
|
||||||
let client_public = reader.read_string().unwrap();
|
let client_public = reader.read_string().unwrap();
|
||||||
|
|
||||||
let config = match &conn.conn_type
|
let config = match &conn.conn_type {
|
||||||
{
|
|
||||||
ConnectionType::Server(config) => config.clone(),
|
ConnectionType::Server(config) => config.clone(),
|
||||||
_ => return KexResult::Error,
|
_ => return KexResult::Error,
|
||||||
};
|
};
|
||||||
|
|
@ -83,27 +81,38 @@ impl KeyExchange for Curve25519 {
|
||||||
secret
|
secret
|
||||||
};
|
};
|
||||||
|
|
||||||
// let server_public = crypto::curve25519::curve25519_base(&server_secret);
|
// let server_public =
|
||||||
|
// crypto::curve25519::curve25519_base(&server_secret);
|
||||||
// let shared_secret = {
|
// let shared_secret = {
|
||||||
// let mut buf = Vec::new();
|
// let mut buf = Vec::new();
|
||||||
// buf.write_mpint(BigInt::from_bytes_be(
|
// buf.write_mpint(BigInt::from_bytes_be(
|
||||||
// Sign::Plus,
|
// Sign::Plus,
|
||||||
// &crypto::curve25519::curve25519(&server_secret, &client_public),
|
// &crypto::curve25519::curve25519(&server_secret,
|
||||||
// )).ok();
|
// &client_public), )).ok();
|
||||||
// buf
|
// buf
|
||||||
// };
|
// };
|
||||||
|
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
|
|
||||||
let server_secret_scalar = Scalar::from_bytes_mod_order(server_secret);
|
let server_secret_scalar =
|
||||||
let server_public = MontgomeryPoint::mul_base(&server_secret_scalar);
|
Scalar::from_bytes_mod_order(server_secret);
|
||||||
|
let server_public =
|
||||||
|
MontgomeryPoint::mul_base(&server_secret_scalar);
|
||||||
let shared_secret = {
|
let shared_secret = {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
let client_public_array: [u8; 32] = client_public.clone().try_into().unwrap(); // TODO
|
let client_public_array: [u8; 32] =
|
||||||
let client_public_point = MontgomeryPoint(client_public_array);
|
client_public.clone().try_into().unwrap(); // TODO
|
||||||
let server_secret_scalar = Scalar::from_bytes_mod_order(server_secret);
|
let client_public_point =
|
||||||
let shared_secret_point = client_public_point * server_secret_scalar;
|
MontgomeryPoint(client_public_array);
|
||||||
buf.write_mpint(BigInt::from_bytes_be(Sign::Plus, &shared_secret_point.to_bytes())).ok();
|
let server_secret_scalar =
|
||||||
|
Scalar::from_bytes_mod_order(server_secret);
|
||||||
|
let shared_secret_point =
|
||||||
|
client_public_point * server_secret_scalar;
|
||||||
|
buf.write_mpint(BigInt::from_bytes_be(
|
||||||
|
Sign::Plus,
|
||||||
|
&shared_secret_point.to_bytes(),
|
||||||
|
))
|
||||||
|
.ok();
|
||||||
buf
|
buf
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -113,16 +122,15 @@ impl KeyExchange for Curve25519 {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
let data = &conn.hash_data;
|
let data = &conn.hash_data;
|
||||||
|
|
||||||
let items =
|
let items = [
|
||||||
[
|
data.client_id.as_ref().unwrap().as_bytes(),
|
||||||
data.client_id.as_ref().unwrap().as_bytes(),
|
data.server_id.as_ref().unwrap().as_bytes(),
|
||||||
data.server_id.as_ref().unwrap().as_bytes(),
|
data.client_kexinit.as_ref().unwrap().as_slice(),
|
||||||
data.client_kexinit.as_ref().unwrap().as_slice(),
|
data.server_kexinit.as_ref().unwrap().as_slice(),
|
||||||
data.server_kexinit.as_ref().unwrap().as_slice(),
|
public_key.as_slice(),
|
||||||
public_key.as_slice(),
|
client_public.as_slice(),
|
||||||
client_public.as_slice(),
|
&server_public.to_bytes(),
|
||||||
&server_public.to_bytes(),
|
];
|
||||||
];
|
|
||||||
|
|
||||||
for item in items.iter() {
|
for item in items.iter() {
|
||||||
buf.write_bytes(item).ok();
|
buf.write_bytes(item).ok();
|
||||||
|
|
|
||||||
14
src/lib.rs
14
src/lib.rs
|
|
@ -9,15 +9,15 @@ extern crate log;
|
||||||
#[cfg(not(target_os = "redox"))]
|
#[cfg(not(target_os = "redox"))]
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
mod error;
|
|
||||||
mod algorithm;
|
mod algorithm;
|
||||||
mod packet;
|
|
||||||
mod message;
|
|
||||||
mod connection;
|
|
||||||
mod key_exchange;
|
|
||||||
mod encryption;
|
|
||||||
mod mac;
|
|
||||||
mod channel;
|
mod channel;
|
||||||
|
mod connection;
|
||||||
|
mod encryption;
|
||||||
|
mod error;
|
||||||
|
mod key_exchange;
|
||||||
|
mod mac;
|
||||||
|
mod message;
|
||||||
|
mod packet;
|
||||||
|
|
||||||
pub mod public_key;
|
pub mod public_key;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
// mod hmac;
|
// mod hmac;
|
||||||
mod hmac_new;
|
mod hmac_new;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,7 @@ pub enum MessageType {
|
||||||
impl From<u8> for MessageType {
|
impl From<u8> for MessageType {
|
||||||
fn from(id: u8) -> Self {
|
fn from(id: u8) -> Self {
|
||||||
use self::MessageType::*;
|
use self::MessageType::*;
|
||||||
match id
|
match id {
|
||||||
{
|
|
||||||
1 => Disconnect,
|
1 => Disconnect,
|
||||||
2 => Ignore,
|
2 => Ignore,
|
||||||
3 => Unimplemented,
|
3 => Unimplemented,
|
||||||
|
|
@ -72,8 +71,7 @@ impl From<u8> for MessageType {
|
||||||
impl From<MessageType> for u8 {
|
impl From<MessageType> for u8 {
|
||||||
fn from(val: MessageType) -> Self {
|
fn from(val: MessageType) -> Self {
|
||||||
use self::MessageType::*;
|
use self::MessageType::*;
|
||||||
match val
|
match val {
|
||||||
{
|
|
||||||
Disconnect => 1,
|
Disconnect => 1,
|
||||||
Ignore => 2,
|
Ignore => 2,
|
||||||
Unimplemented => 3,
|
Unimplemented => 3,
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@ impl Packet {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn msg_type(&self) -> MessageType {
|
pub fn msg_type(&self) -> MessageType {
|
||||||
match self
|
match self {
|
||||||
{
|
|
||||||
Packet::Raw(data, _) => data[5],
|
Packet::Raw(data, _) => data[5],
|
||||||
Packet::Payload(data) => data[0],
|
Packet::Payload(data) => data[0],
|
||||||
}.into()
|
}
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_from<R: io::Read>(stream: &mut R) -> Result<Packet> {
|
pub fn read_from<R: io::Read>(stream: &mut R) -> Result<Packet> {
|
||||||
|
|
@ -48,8 +48,7 @@ impl Packet {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_to<W: io::Write>(&self, stream: &mut W) -> Result<()> {
|
pub fn write_to<W: io::Write>(&self, stream: &mut W) -> Result<()> {
|
||||||
match self
|
match self {
|
||||||
{
|
|
||||||
Packet::Raw(data, _) => {
|
Packet::Raw(data, _) => {
|
||||||
stream.write_all(data)?;
|
stream.write_all(data)?;
|
||||||
stream.flush()
|
stream.flush()
|
||||||
|
|
@ -69,24 +68,21 @@ impl Packet {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn payload(self) -> Vec<u8> {
|
pub fn payload(self) -> Vec<u8> {
|
||||||
match self
|
match self {
|
||||||
{
|
|
||||||
Packet::Raw(data, payload_len) => data[5..payload_len + 5].to_vec(),
|
Packet::Raw(data, payload_len) => data[5..payload_len + 5].to_vec(),
|
||||||
Packet::Payload(payload) => payload,
|
Packet::Payload(payload) => payload,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn data(&self) -> &[u8] {
|
pub fn data(&self) -> &[u8] {
|
||||||
match self
|
match self {
|
||||||
{
|
|
||||||
Packet::Raw(data, _) => data,
|
Packet::Raw(data, _) => data,
|
||||||
Packet::Payload(payload) => payload,
|
Packet::Payload(payload) => payload,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_raw(self) -> Result<Packet> {
|
pub fn into_raw(self) -> Result<Packet> {
|
||||||
match self
|
match self {
|
||||||
{
|
|
||||||
Packet::Raw(_, _) => Ok(self),
|
Packet::Raw(_, _) => Ok(self),
|
||||||
Packet::Payload(ref payload) => {
|
Packet::Payload(ref payload) => {
|
||||||
let mut buf = Vec::with_capacity(payload.len());
|
let mut buf = Vec::with_capacity(payload.len());
|
||||||
|
|
@ -97,8 +93,7 @@ impl Packet {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reader(&self) -> BufReader<&[u8]> {
|
pub fn reader(&self) -> BufReader<&[u8]> {
|
||||||
match self
|
match self {
|
||||||
{
|
|
||||||
&Packet::Raw(ref data, payload_len) => {
|
&Packet::Raw(ref data, payload_len) => {
|
||||||
BufReader::new(&data.as_slice()[6..payload_len + 5])
|
BufReader::new(&data.as_slice()[6..payload_len + 5])
|
||||||
}
|
}
|
||||||
|
|
@ -109,8 +104,7 @@ impl Packet {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn payload_len(&self) -> usize {
|
pub fn payload_len(&self) -> usize {
|
||||||
match self
|
match self {
|
||||||
{
|
|
||||||
&Packet::Raw(_, payload_len) => payload_len,
|
&Packet::Raw(_, payload_len) => payload_len,
|
||||||
Packet::Payload(payload) => payload.len(),
|
Packet::Payload(payload) => payload.len(),
|
||||||
}
|
}
|
||||||
|
|
@ -134,8 +128,7 @@ impl Packet {
|
||||||
|
|
||||||
impl Write for Packet {
|
impl Write for Packet {
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||||
match *self
|
match *self {
|
||||||
{
|
|
||||||
Packet::Payload(ref mut payload) => payload.write(buf),
|
Packet::Payload(ref mut payload) => payload.write(buf),
|
||||||
Packet::Raw(ref mut data, ref mut payload_len) => {
|
Packet::Raw(ref mut data, ref mut payload_len) => {
|
||||||
let count = data.write(buf)?;
|
let count = data.write(buf)?;
|
||||||
|
|
@ -186,12 +179,10 @@ pub trait ReadPacketExt: ReadBytesExt {
|
||||||
|
|
||||||
fn read_enum_list<T: FromStr>(&mut self) -> Result<Vec<T>> {
|
fn read_enum_list<T: FromStr>(&mut self) -> Result<Vec<T>> {
|
||||||
let string = self.read_utf8()?;
|
let string = self.read_utf8()?;
|
||||||
Ok(
|
Ok(string
|
||||||
string
|
.split(",")
|
||||||
.split(",")
|
.filter_map(|l| T::from_str(l).ok())
|
||||||
.filter_map(|l| T::from_str(l).ok())
|
.collect())
|
||||||
.collect(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_name_list(&mut self) -> Result<Vec<String>> {
|
fn read_name_list(&mut self) -> Result<Vec<String>> {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ pub static ED25519: CryptoSystem = CryptoSystem {
|
||||||
struct Ed25519KeyPair {
|
struct Ed25519KeyPair {
|
||||||
// This should be 32 bytes as mandated for [ed25519](https://www.rfc-editor.org/rfc/rfc8032#section-5.1.5)
|
// This should be 32 bytes as mandated for [ed25519](https://www.rfc-editor.org/rfc/rfc8032#section-5.1.5)
|
||||||
private: Option<SigningKey>, //[u8; 64]>,
|
private: Option<SigningKey>, //[u8; 64]>,
|
||||||
public: VerifyingKey, // [u8; 32],
|
public: VerifyingKey, // [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ed25519KeyPair {
|
impl Ed25519KeyPair {
|
||||||
|
|
@ -39,7 +39,10 @@ impl Ed25519KeyPair {
|
||||||
use crate::packet::ReadPacketExt;
|
use crate::packet::ReadPacketExt;
|
||||||
|
|
||||||
if r.read_utf8()? != "ssh-ed25519" {
|
if r.read_utf8()? != "ssh-ed25519" {
|
||||||
return Err(io::Error::new(InvalidData, "Not a ED25519 key (in custom format), invalid header"));
|
return Err(io::Error::new(
|
||||||
|
InvalidData,
|
||||||
|
"Not a ED25519 key (in custom format), invalid header",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.read_uint32()? != 32 {
|
if r.read_uint32()? != 32 {
|
||||||
|
|
@ -74,8 +77,7 @@ impl Ed25519KeyPair {
|
||||||
|
|
||||||
let mut public = [0u8; 32];
|
let mut public = [0u8; 32];
|
||||||
r.read_exact(&mut public)?;
|
r.read_exact(&mut public)?;
|
||||||
let public = VerifyingKey::from_bytes(&public)
|
let public = VerifyingKey::from_bytes(&public).unwrap(); // TODO
|
||||||
.unwrap(); // TODO
|
|
||||||
|
|
||||||
Ok(Box::new(Ed25519KeyPair {
|
Ok(Box::new(Ed25519KeyPair {
|
||||||
private: None,
|
private: None,
|
||||||
|
|
@ -107,12 +109,17 @@ impl KeyPair for Ed25519KeyPair {
|
||||||
let received_id = reader.read_string().unwrap_or_default();
|
let received_id = reader.read_string().unwrap_or_default();
|
||||||
|
|
||||||
if received_id == EXPECTED_ID {
|
if received_id == EXPECTED_ID {
|
||||||
if let Ok(sig) = reader.read_string() { // TODO: .read_string() {
|
if let Ok(sig) = reader.read_string() {
|
||||||
let sig_array: &[u8; 64] = sig.as_slice().try_into().expect("slice with incorrect length"); // TODO
|
// TODO: .read_string() {
|
||||||
|
let sig_array: &[u8; 64] = sig
|
||||||
|
.as_slice()
|
||||||
|
.try_into()
|
||||||
|
.expect("slice with incorrect length"); // TODO
|
||||||
let sig = Signature::from_bytes(sig_array); // TODO
|
let sig = Signature::from_bytes(sig_array); // TODO
|
||||||
let res = self.public.verify_strict(data, &sig);
|
let res = self.public.verify_strict(data, &sig);
|
||||||
return Ok(res.is_ok());
|
return Ok(res.is_ok());
|
||||||
// return Ok(ed25519::verify(data, &self.public, sig.as_slice()));
|
// return Ok(ed25519::verify(data, &self.public,
|
||||||
|
// sig.as_slice()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(KeyPairIdValidationError {
|
Err(KeyPairIdValidationError {
|
||||||
|
|
@ -130,7 +137,8 @@ impl KeyPair for Ed25519KeyPair {
|
||||||
result.write_string("ssh-ed25519")?;
|
result.write_string("ssh-ed25519")?;
|
||||||
result.write_bytes(&sig.to_bytes())?;
|
result.write_bytes(&sig.to_bytes())?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Err(SigningError::NoPrivateKey)
|
Err(SigningError::NoPrivateKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,11 @@ pub trait KeyPair: Sync + Send {
|
||||||
|
|
||||||
fn has_private(&self) -> bool;
|
fn has_private(&self) -> bool;
|
||||||
|
|
||||||
fn verify(&self, data: &[u8], signature: &[u8]) -> Result<bool, KeyPairIdValidationError>;
|
fn verify(
|
||||||
|
&self,
|
||||||
|
data: &[u8],
|
||||||
|
signature: &[u8],
|
||||||
|
) -> Result<bool, KeyPairIdValidationError>;
|
||||||
fn sign(&self, data: &[u8]) -> Result<Vec<u8>, SigningError>;
|
fn sign(&self, data: &[u8]) -> Result<Vec<u8>, SigningError>;
|
||||||
|
|
||||||
fn write_public(&self, w: &mut dyn Write) -> io::Result<()>;
|
fn write_public(&self, w: &mut dyn Write) -> io::Result<()>;
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@ pub struct Server {
|
||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
pub fn with_config(config: ServerConfig) -> Server {
|
pub fn with_config(config: ServerConfig) -> Server {
|
||||||
Server { config: Arc::new(config) }
|
Server {
|
||||||
|
config: Arc::new(config),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&self) -> io::Result<()> {
|
pub fn run(&self) -> io::Result<()> {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::io::Result;
|
use std::io::Result;
|
||||||
use std::os::unix::io::RawFd;
|
|
||||||
use std::os::fd::AsRawFd;
|
use std::os::fd::AsRawFd;
|
||||||
|
use std::os::unix::io::RawFd;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub fn before_exec() -> Result<()> {
|
pub fn before_exec() -> Result<()> {
|
||||||
|
|
@ -8,7 +8,9 @@ pub fn before_exec() -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fork() -> usize {
|
pub fn fork() -> usize {
|
||||||
todo!("You must specify -f, the old forking for Redox doesn't work anyway.");
|
todo!(
|
||||||
|
"You must specify -f, the old forking for Redox doesn't work anyway."
|
||||||
|
);
|
||||||
// The following on't work anyway
|
// The following on't work anyway
|
||||||
// but will panic due to missing implementation
|
// but will panic due to missing implementation
|
||||||
// extern crate syscall;
|
// extern crate syscall;
|
||||||
|
|
@ -20,8 +22,7 @@ pub fn set_winsize(fd: RawFd, row: u16, col: u16, xpixel: u16, ypixel: u16) {}
|
||||||
pub fn getpty() -> (RawFd, PathBuf) {
|
pub fn getpty() -> (RawFd, PathBuf) {
|
||||||
use libredox::{call, flag};
|
use libredox::{call, flag};
|
||||||
|
|
||||||
let master = call::open("pty:", flag::O_RDWR | flag::O_CREAT, 777)
|
let master = call::open("pty:", flag::O_RDWR | flag::O_CREAT, 777).unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut buf: [u8; 4096] = [0; 4096];
|
let mut buf: [u8; 4096] = [0; 4096];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
extern crate ssh;
|
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
extern crate ssh;
|
||||||
|
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue