mirror of
https://github.com/Noratrieb/cluelessh.git
synced 2026-01-15 17:05:05 +01:00
sorta works
This commit is contained in:
parent
2b2e2ac1f0
commit
bc7e12e50b
2 changed files with 166 additions and 10 deletions
|
|
@ -1,15 +1,29 @@
|
|||
use tracing::debug;
|
||||
use std::collections::VecDeque;
|
||||
use tracing::{debug, warn};
|
||||
|
||||
use crate::packet::Packet;
|
||||
use crate::parse::Parser;
|
||||
use crate::Result;
|
||||
use crate::client_error;
|
||||
use crate::packet::Packet;
|
||||
use crate::parse::{Parser, Writer};
|
||||
use crate::Result;
|
||||
|
||||
pub(crate) struct ServerChannelsState {}
|
||||
pub(crate) struct ServerChannelsState {
|
||||
packets_to_send: VecDeque<Packet>,
|
||||
channels: Vec<SessionChannel>,
|
||||
}
|
||||
|
||||
struct SessionChannel {
|
||||
peer_channel: u32,
|
||||
has_pty: bool,
|
||||
has_shell: bool,
|
||||
sent_bytes: Vec<u8>,
|
||||
}
|
||||
|
||||
impl ServerChannelsState {
|
||||
pub(crate) fn new() -> Self {
|
||||
ServerChannelsState {}
|
||||
ServerChannelsState {
|
||||
packets_to_send: VecDeque::new(),
|
||||
channels: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn on_packet(&mut self, packet_type: u8, mut payload: Parser<'_>) -> Result<()> {
|
||||
|
|
@ -25,9 +39,114 @@ impl ServerChannelsState {
|
|||
|
||||
match channel_type {
|
||||
"session" => {
|
||||
todo!("open session")
|
||||
let our_number = self.channels.len() as u32;
|
||||
|
||||
let mut confirm = Writer::new();
|
||||
confirm.u8(Packet::SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
|
||||
confirm.u32(our_number);
|
||||
confirm.u32(sender_channel);
|
||||
confirm.u32(initial_window_size);
|
||||
confirm.u32(max_packet_size);
|
||||
|
||||
self.channels.push(SessionChannel {
|
||||
peer_channel: sender_channel,
|
||||
has_pty: false,
|
||||
has_shell: false,
|
||||
sent_bytes: Vec::new(),
|
||||
});
|
||||
|
||||
self.packets_to_send.push_back(Packet {
|
||||
payload: confirm.finish(),
|
||||
});
|
||||
|
||||
debug!(?channel_type, ?our_number, "Successfully opened channel");
|
||||
}
|
||||
_ => {
|
||||
let mut failure = Writer::new();
|
||||
failure.u8(Packet::SSH_MSG_CHANNEL_OPEN_FAILURE);
|
||||
failure.u32(sender_channel);
|
||||
failure.u32(3); // SSH_OPEN_UNKNOWN_CHANNEL_TYPE
|
||||
failure.string(b"unknown channel type");
|
||||
failure.string(b"en_US");
|
||||
|
||||
self.packets_to_send.push_back(Packet {
|
||||
payload: failure.finish(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Packet::SSH_MSG_CHANNEL_DATA => {
|
||||
let our_channel = payload.u32()?;
|
||||
let data = payload.string()?;
|
||||
|
||||
let channel = self.channel(our_channel)?;
|
||||
channel.recv_bytes(data);
|
||||
|
||||
let mut reply = Writer::new();
|
||||
reply.u8(Packet::SSH_MSG_CHANNEL_DATA);
|
||||
reply.u32(channel.peer_channel);
|
||||
reply.string(data);
|
||||
self.packets_to_send.push_back(Packet {
|
||||
payload: reply.finish(),
|
||||
});
|
||||
}
|
||||
Packet::SSH_MSG_CHANNEL_REQUEST => {
|
||||
let our_channel = payload.u32()?;
|
||||
let request_type = payload.utf8_string()?;
|
||||
let want_reply = payload.bool()?;
|
||||
|
||||
debug!(?our_channel, ?request_type, "Got channel request");
|
||||
|
||||
let channel = self.channel(our_channel)?;
|
||||
let peer_channel = channel.peer_channel;
|
||||
|
||||
match request_type {
|
||||
"pty-req" => {
|
||||
let term = payload.utf8_string()?;
|
||||
let width_chars = payload.u32()?;
|
||||
let height_rows = payload.u32()?;
|
||||
let _width_px = payload.u32()?;
|
||||
let _height_px = payload.u32()?;
|
||||
let _term_modes = payload.string()?;
|
||||
|
||||
debug!(
|
||||
?our_channel,
|
||||
?term,
|
||||
?width_chars,
|
||||
?height_rows,
|
||||
"Trying to open a terminal"
|
||||
);
|
||||
|
||||
// Faithfully allocate the PTY.
|
||||
channel.has_pty = true;
|
||||
|
||||
if want_reply {
|
||||
self.send_channel_success(peer_channel);
|
||||
}
|
||||
}
|
||||
"shell" => {
|
||||
if !channel.has_pty {
|
||||
self.send_channel_failure(peer_channel);
|
||||
}
|
||||
|
||||
// Sure! (reborrow)
|
||||
let channel = self.channel(our_channel)?;
|
||||
channel.has_shell = true;
|
||||
|
||||
debug!(?our_channel, "Opening shell");
|
||||
|
||||
if want_reply {
|
||||
self.send_channel_success(peer_channel);
|
||||
}
|
||||
}
|
||||
"signal" => {
|
||||
debug!(?our_channel, "Received signal");
|
||||
// Ignore signals, something we can do.
|
||||
}
|
||||
_ => {
|
||||
warn!(?request_type, ?our_channel, "Unknown channel request");
|
||||
self.send_channel_failure(peer_channel);
|
||||
}
|
||||
_ => todo!("response with SSH_MSG_CHANNEL_OPEN_FAILURE"),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
|
@ -37,4 +156,38 @@ impl ServerChannelsState {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn packets_to_send(&mut self) -> impl Iterator<Item = Packet> + '_ {
|
||||
self.packets_to_send.drain(..)
|
||||
}
|
||||
|
||||
fn send_channel_success(&mut self, recipient_channel: u32) {
|
||||
let mut failure = Writer::new();
|
||||
failure.u8(Packet::SSH_MSG_CHANNEL_SUCCESS);
|
||||
failure.u32(recipient_channel);
|
||||
self.packets_to_send.push_back(Packet {
|
||||
payload: failure.finish(),
|
||||
});
|
||||
}
|
||||
|
||||
fn send_channel_failure(&mut self, recipient_channel: u32) {
|
||||
let mut failure = Writer::new();
|
||||
failure.u8(Packet::SSH_MSG_CHANNEL_FAILURE);
|
||||
failure.u32(recipient_channel);
|
||||
self.packets_to_send.push_back(Packet {
|
||||
payload: failure.finish(),
|
||||
});
|
||||
}
|
||||
|
||||
fn channel(&mut self, number: u32) -> Result<&mut SessionChannel> {
|
||||
self.channels
|
||||
.get_mut(number as usize)
|
||||
.ok_or_else(|| client_error!("unknown channel: {number}"))
|
||||
}
|
||||
}
|
||||
|
||||
impl SessionChannel {
|
||||
fn recv_bytes(&mut self, bytes: &[u8]) {
|
||||
self.sent_bytes.extend_from_slice(bytes);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -406,8 +406,8 @@ impl ServerConnection {
|
|||
|
||||
let mut banner = Writer::new();
|
||||
banner.u8(Packet::SSH_MSG_USERAUTH_BANNER);
|
||||
banner.string(b"this system ONLY allows catgirls to enter.\r\nall other attempts WILL be prosecuted to the full extent of the rawr!!\r\n");
|
||||
banner.string(b"en-US");
|
||||
banner.string(b"!! this system ONLY allows catgirls to enter !!\r\n!! all other attempts WILL be prosecuted to the full extent of the rawr !!\r\n");
|
||||
banner.string(b"en_US");
|
||||
self.packet_transport.queue_packet(Packet {
|
||||
payload: banner.finish(),
|
||||
});
|
||||
|
|
@ -431,6 +431,9 @@ impl ServerConnection {
|
|||
// Connection-related packets
|
||||
90..128 => {
|
||||
con.on_packet(packet_type, payload)?;
|
||||
for packet in con.packets_to_send() {
|
||||
self.packet_transport.queue_packet(packet);
|
||||
}
|
||||
}
|
||||
Packet::SSH_MSG_GLOBAL_REQUEST => {
|
||||
let request_name = payload.utf8_string()?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue