#2, send client encodings
This commit is contained in:
parent
098629536a
commit
0762d972a4
@ -194,6 +194,12 @@ impl Component for PageRemote {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rendered(&mut self, first_render: bool) {
|
||||||
|
if first_render {
|
||||||
|
self.handler.set_resolution(1366, 768);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl PageRemote
|
// impl PageRemote
|
||||||
@ -250,7 +256,7 @@ impl PageRemote {
|
|||||||
let canvas = self.canvas.cast::<HtmlCanvasElement>().unwrap();
|
let canvas = self.canvas.cast::<HtmlCanvasElement>().unwrap();
|
||||||
canvas.set_width(width as u32);
|
canvas.set_width(width as u32);
|
||||||
canvas.set_height(height as u32);
|
canvas.set_height(height as u32);
|
||||||
self.link.send_message(RemoteMsg::RequireFrame(1));
|
self.link.send_message(RemoteMsg::RequireFrame(0));
|
||||||
let ctx = match &self.canvas_ctx {
|
let ctx = match &self.canvas_ctx {
|
||||||
Some(ctx) => ctx,
|
Some(ctx) => ctx,
|
||||||
None => {
|
None => {
|
||||||
|
@ -43,6 +43,10 @@ where
|
|||||||
self.inner.set_credential(username, password);
|
self.inner.set_credential(username, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_resolution(&mut self, width: u16, height: u16) {
|
||||||
|
self.inner.set_resolution(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn require_frame(&mut self, incremental: u8) {
|
pub fn require_frame(&mut self, incremental: u8) {
|
||||||
self.inner.require_frame(incremental);
|
self.inner.require_frame(incremental);
|
||||||
}
|
}
|
||||||
@ -53,26 +57,37 @@ pub trait ProtocalImpl {
|
|||||||
fn do_input(&mut self, input: Vec<u8>);
|
fn do_input(&mut self, input: Vec<u8>);
|
||||||
fn get_output(&mut self) -> Vec<ProtocalHandlerOutput>;
|
fn get_output(&mut self) -> Vec<ProtocalHandlerOutput>;
|
||||||
fn set_credential(&mut self, username: &str, password: &str);
|
fn set_credential(&mut self, username: &str, password: &str);
|
||||||
|
fn set_resolution(&mut self, width: u16, height: u16);
|
||||||
fn require_frame(&mut self, incremental: u8);
|
fn require_frame(&mut self, incremental: u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StreamReader {
|
pub struct StreamReader {
|
||||||
inner: Vec<Vec<u8>>,
|
inner: Vec<Vec<u8>>,
|
||||||
|
remain: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl StreamReader {
|
impl StreamReader {
|
||||||
pub fn new(bufs: Vec<Vec<u8>>) -> Self {
|
pub fn new(bufs: Vec<Vec<u8>>) -> Self {
|
||||||
Self { inner: bufs }
|
Self {
|
||||||
|
inner: bufs,
|
||||||
|
remain: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn append(&mut self, buf: Vec<u8>) {
|
pub fn append(&mut self, buf: Vec<u8>) {
|
||||||
|
self.remain += buf.len();
|
||||||
self.inner.push(buf);
|
self.inner.push(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remain(&self) -> usize {
|
||||||
|
self.remain
|
||||||
|
}
|
||||||
|
|
||||||
pub fn read_exact_vec(&mut self, out_vec: &mut Vec<u8>, n: usize) {
|
pub fn read_exact_vec(&mut self, out_vec: &mut Vec<u8>, n: usize) {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let mut left = n;
|
let mut left = n;
|
||||||
|
self.remain -= n;
|
||||||
while i < n {
|
while i < n {
|
||||||
if self.inner[0].len() > left {
|
if self.inner[0].len() > left {
|
||||||
for it in self.inner[0].drain(0..left) {
|
for it in self.inner[0].drain(0..left) {
|
||||||
@ -92,6 +107,7 @@ impl StreamReader {
|
|||||||
pub fn read_exact(&mut self, out_buf: &mut [u8], n: usize) {
|
pub fn read_exact(&mut self, out_buf: &mut [u8], n: usize) {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let mut left = n;
|
let mut left = n;
|
||||||
|
self.remain -= n;
|
||||||
while i < n {
|
while i < n {
|
||||||
if self.inner[0].len() > left {
|
if self.inner[0].len() > left {
|
||||||
out_buf[i..i + left].copy_from_slice(&self.inner[0][0..left]);
|
out_buf[i..i + left].copy_from_slice(&self.inner[0][0..left]);
|
||||||
|
@ -22,6 +22,19 @@ pub enum SecurityType {
|
|||||||
// VeNCrypt = 19,
|
// VeNCrypt = 19,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum VncEncoding {
|
||||||
|
Raw = 0,
|
||||||
|
CopyRect = 1,
|
||||||
|
RRE = 2,
|
||||||
|
Hextile = 5,
|
||||||
|
TRLE = 15,
|
||||||
|
ZRLE = 16,
|
||||||
|
CursorPseudo = -239,
|
||||||
|
DesktopSizePseudo = -223,
|
||||||
|
}
|
||||||
|
|
||||||
pub enum VncState {
|
pub enum VncState {
|
||||||
Init,
|
Init,
|
||||||
Handshake,
|
Handshake,
|
||||||
@ -40,9 +53,10 @@ pub enum ServerMessage {
|
|||||||
|
|
||||||
pub struct VncHandler {
|
pub struct VncHandler {
|
||||||
state: VncState,
|
state: VncState,
|
||||||
|
// supported_versions: Vec<u8>,
|
||||||
|
supported_encodings: Vec<VncEncoding>,
|
||||||
security_type: SecurityType,
|
security_type: SecurityType,
|
||||||
challenge: [u8; 16],
|
challenge: [u8; 16],
|
||||||
buf_num: usize,
|
|
||||||
reader: StreamReader,
|
reader: StreamReader,
|
||||||
require: usize,
|
require: usize,
|
||||||
width: u16,
|
width: u16,
|
||||||
@ -60,9 +74,18 @@ impl ProtocalImpl for VncHandler {
|
|||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
state: VncState::Init,
|
state: VncState::Init,
|
||||||
|
supported_encodings: vec![
|
||||||
|
VncEncoding::Raw,
|
||||||
|
// VncEncoding::CopyRect,
|
||||||
|
// VncEncoding::RRE,
|
||||||
|
// VncEncoding::Hextile,
|
||||||
|
// VncEncoding::TRLE,
|
||||||
|
// VncEncoding::ZRLE,
|
||||||
|
// VncEncoding::CursorPseudo,
|
||||||
|
// VncEncoding::DesktopSizePseudo,
|
||||||
|
],
|
||||||
security_type: SecurityType::Invalid,
|
security_type: SecurityType::Invalid,
|
||||||
challenge: [0; 16],
|
challenge: [0; 16],
|
||||||
buf_num: 0,
|
|
||||||
reader: StreamReader::new(Vec::with_capacity(10)),
|
reader: StreamReader::new(Vec::with_capacity(10)),
|
||||||
require: 12, // the handleshake message length
|
require: 12, // the handleshake message length
|
||||||
width: 0,
|
width: 0,
|
||||||
@ -78,16 +101,20 @@ impl ProtocalImpl for VncHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn do_input(&mut self, input: Vec<u8>) {
|
fn do_input(&mut self, input: Vec<u8>) {
|
||||||
self.buf_num += input.len();
|
|
||||||
// ConsoleService::info(&format!(
|
// ConsoleService::info(&format!(
|
||||||
// "VNC input {}, left {}, require {}",
|
// "VNC input {}, left {}, require {}",
|
||||||
// input.len(),
|
// input.len(),
|
||||||
// self.buf_num,
|
// self.reader.remain(),
|
||||||
// self.require
|
// self.require
|
||||||
// ));
|
// ));
|
||||||
self.reader.append(input);
|
self.reader.append(input);
|
||||||
while self.buf_num >= self.require {
|
while self.reader.remain() >= self.require {
|
||||||
self.handle_input();
|
self.handle_input();
|
||||||
|
// ConsoleService::info(&format!(
|
||||||
|
// "left {}, require {}",
|
||||||
|
// self.reader.remain(),
|
||||||
|
// self.require
|
||||||
|
// ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +158,16 @@ impl ProtocalImpl for VncHandler {
|
|||||||
self.require = 4; // the auth result message length
|
self.require = 4; // the auth result message length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_resolution(&mut self, _width: u16, _height: u16) {
|
||||||
|
// VNC client doen't support resolution change
|
||||||
|
}
|
||||||
|
|
||||||
fn require_frame(&mut self, incremental: u8) {
|
fn require_frame(&mut self, incremental: u8) {
|
||||||
|
if 0 == incremental {
|
||||||
|
// first frame
|
||||||
|
// set the client encoding
|
||||||
|
self.send_client_encodings();
|
||||||
|
}
|
||||||
if let ServerMessage::None = self.msg_handling {
|
if let ServerMessage::None = self.msg_handling {
|
||||||
self.framebuffer_update_request(incremental)
|
self.framebuffer_update_request(incremental)
|
||||||
}
|
}
|
||||||
@ -141,55 +177,45 @@ impl ProtocalImpl for VncHandler {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl VncHandler {
|
impl VncHandler {
|
||||||
fn read_u8(&mut self) -> u8 {
|
fn read_u8(&mut self) -> u8 {
|
||||||
self.buf_num -= 1;
|
|
||||||
self.reader.read_u8()
|
self.reader.read_u8()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_u16(&mut self) -> u16 {
|
fn read_u16(&mut self) -> u16 {
|
||||||
self.buf_num -= 2;
|
|
||||||
self.reader.read_u16()
|
self.reader.read_u16()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_u32(&mut self) -> u32 {
|
fn read_u32(&mut self) -> u32 {
|
||||||
self.buf_num -= 4;
|
|
||||||
self.reader.read_u32()
|
self.reader.read_u32()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_u64(&mut self) -> u64 {
|
fn read_u64(&mut self) -> u64 {
|
||||||
self.buf_num -= 8;
|
|
||||||
self.reader.read_u64()
|
self.reader.read_u64()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_exact_vec(&mut self, out_vec: &mut Vec<u8>, len: usize) {
|
fn read_exact_vec(&mut self, out_vec: &mut Vec<u8>, len: usize) {
|
||||||
self.buf_num -= len;
|
|
||||||
self.reader.read_exact_vec(out_vec, len);
|
self.reader.read_exact_vec(out_vec, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_exact(&mut self, buf: &mut [u8], len: usize) {
|
fn read_exact(&mut self, buf: &mut [u8], len: usize) {
|
||||||
self.buf_num -= len;
|
|
||||||
self.reader.read_exact(buf, len)
|
self.reader.read_exact(buf, len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_string(&mut self, len: usize) -> String {
|
fn read_string(&mut self, len: usize) -> String {
|
||||||
self.buf_num -= len;
|
|
||||||
self.reader.read_string(len)
|
self.reader.read_string(len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_string_l8(&mut self) -> String {
|
fn read_string_l8(&mut self) -> String {
|
||||||
let len = self.read_u8() as usize;
|
let len = self.read_u8() as usize;
|
||||||
self.buf_num -= len;
|
|
||||||
self.reader.read_string(len)
|
self.reader.read_string(len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_string_l16(&mut self) -> String {
|
fn read_string_l16(&mut self) -> String {
|
||||||
let len = self.read_u16() as usize;
|
let len = self.read_u16() as usize;
|
||||||
self.buf_num -= len;
|
|
||||||
self.reader.read_string(len)
|
self.reader.read_string(len)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_string_l32(&mut self) -> String {
|
fn read_string_l32(&mut self) -> String {
|
||||||
let len = self.read_u32() as usize;
|
let len = self.read_u32() as usize;
|
||||||
self.buf_num -= len;
|
|
||||||
self.reader.read_string(len)
|
self.reader.read_string(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,10 +232,38 @@ impl VncHandler {
|
|||||||
self.require = 25; // the minimal length of server_init message
|
self.require = 25; // the minimal length of server_init message
|
||||||
|
|
||||||
// send client_init message
|
// send client_init message
|
||||||
let shared_flag = 0;
|
let shared_flag = 1;
|
||||||
self.outbuf.push(shared_flag);
|
self.outbuf.push(shared_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// +--------------+--------------+---------------------+
|
||||||
|
// | No. of bytes | Type [Value] | Description |
|
||||||
|
// +--------------+--------------+---------------------+
|
||||||
|
// | 1 | U8 [2] | message-type |
|
||||||
|
// | 1 | | padding |
|
||||||
|
// | 2 | U16 | number-of-encodings |
|
||||||
|
// +--------------+--------------+---------------------+
|
||||||
|
|
||||||
|
// This is followed by number-of-encodings repetitions of the following:
|
||||||
|
// +--------------+--------------+---------------+
|
||||||
|
// | No. of bytes | Type [Value] | Description |
|
||||||
|
// +--------------+--------------+---------------+
|
||||||
|
// | 4 | S32 | encoding-type |
|
||||||
|
// +--------------+--------------+---------------+
|
||||||
|
fn send_client_encodings(&mut self) {
|
||||||
|
let mut out = Vec::with_capacity(10);
|
||||||
|
let mut sw = StreamWriter::new(&mut out);
|
||||||
|
sw.write_u8(2); // message-type
|
||||||
|
sw.write_u8(0); // padding
|
||||||
|
sw.write_u16(self.supported_encodings.len().try_into().unwrap()); // number-of-encodings
|
||||||
|
|
||||||
|
for i in &self.supported_encodings {
|
||||||
|
sw.write_u32(*i as u32);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.outbuf.extend_from_slice(&out);
|
||||||
|
}
|
||||||
|
|
||||||
// No. of bytes Type [Value] Description
|
// No. of bytes Type [Value] Description
|
||||||
// 1 CARD8 3 message-type
|
// 1 CARD8 3 message-type
|
||||||
// 1 CARD8 incremental
|
// 1 CARD8 incremental
|
||||||
@ -262,6 +316,7 @@ impl VncHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn do_authenticate(&mut self) {
|
fn do_authenticate(&mut self) {
|
||||||
|
// ConsoleService::log(&format!("VNC: do_authenticate {}", self.reader.remain()));
|
||||||
if self.security_type == SecurityType::Invalid {
|
if self.security_type == SecurityType::Invalid {
|
||||||
let auth_type = self.read_u32();
|
let auth_type = self.read_u32();
|
||||||
match auth_type {
|
match auth_type {
|
||||||
@ -369,18 +424,19 @@ impl VncHandler {
|
|||||||
let width = self.read_u16();
|
let width = self.read_u16();
|
||||||
let height = self.read_u16();
|
let height = self.read_u16();
|
||||||
let encoding_type = self.read_u32();
|
let encoding_type = self.read_u32();
|
||||||
match encoding_type {
|
let encoding_enum = unsafe { std::mem::transmute(encoding_type) };
|
||||||
0 => self.handle_raw_encoding(x, y, width, height),
|
match encoding_enum {
|
||||||
1 => self.handle_copy_rect_encoding(x, y, width, height),
|
VncEncoding::Raw => self.handle_raw_encoding(x, y, width, height),
|
||||||
2 => self.handle_rre_encoding(x, y, width, height),
|
VncEncoding::CopyRect => self.handle_copy_rect_encoding(x, y, width, height),
|
||||||
4 => self.handle_corre_encoding(x, y, width, height),
|
VncEncoding::RRE => self.handle_rre_encoding(x, y, width, height),
|
||||||
5 => self.handle_hextile_encoding(x, y, width, height),
|
VncEncoding::Hextile => self.handle_hextile_encoding(x, y, width, height),
|
||||||
_ => {
|
VncEncoding::TRLE => self.handle_trle_encoding(x, y, width, height),
|
||||||
ConsoleService::log(&format!(
|
VncEncoding::ZRLE => self.handle_zrle_encoding(x, y, width, height),
|
||||||
"VNC: Unsupported encoding type {}",
|
VncEncoding::CursorPseudo => {
|
||||||
encoding_type
|
self.handle_cursor_pseudo_encoding(x, y, width, height)
|
||||||
));
|
}
|
||||||
self.disconnect_with_err(VNC_FAILED)
|
VncEncoding::DesktopSizePseudo => {
|
||||||
|
self.handle_desktop_size_pseudo_encoding(x, y, width, height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -517,11 +573,23 @@ impl VncHandler {
|
|||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_corre_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
|
fn handle_hextile_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_hextile_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
|
fn handle_trle_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_zrle_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_cursor_pseudo_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_desktop_size_pseudo_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user