vnc start auth
This commit is contained in:
parent
d350dbe0bf
commit
999edd10e7
@ -3,6 +3,8 @@ use yew::services::websocket::{WebSocketService, WebSocketStatus, WebSocketTask}
|
||||
use yew::services::ConsoleService;
|
||||
use yew::{format::Binary, utils::host};
|
||||
|
||||
use crate::utils::WeakComponentLink;
|
||||
|
||||
pub struct WebsocketCtx {
|
||||
ws: Option<WebSocketTask>,
|
||||
link: ComponentLink<Self>,
|
||||
@ -14,6 +16,7 @@ pub struct WebsocketCtx {
|
||||
pub struct WebsocketProps {
|
||||
#[prop_or_default]
|
||||
pub onrecv: Callback<Vec<u8>>,
|
||||
pub weak_link: WeakComponentLink<WebsocketCtx>,
|
||||
}
|
||||
|
||||
pub enum WebsocketMsg {
|
||||
@ -29,6 +32,7 @@ impl Component for WebsocketCtx {
|
||||
type Properties = WebsocketProps;
|
||||
|
||||
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||
props.weak_link.borrow_mut().replace(link.clone());
|
||||
Self {
|
||||
ws: None,
|
||||
link: link,
|
||||
|
@ -1,6 +1,7 @@
|
||||
mod app;
|
||||
mod components;
|
||||
mod pages;
|
||||
mod protocal;
|
||||
mod utils;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
@ -1,6 +1,7 @@
|
||||
use serde_json::{json, Value};
|
||||
use yew::{
|
||||
format::Json,
|
||||
html,
|
||||
prelude::*,
|
||||
services::{
|
||||
fetch::{FetchTask, Request, Response},
|
||||
@ -8,7 +9,12 @@ use yew::{
|
||||
},
|
||||
};
|
||||
|
||||
use crate::components;
|
||||
use crate::components::ws::WebsocketMsg;
|
||||
use crate::{
|
||||
components,
|
||||
protocal::{common::*, vnc::VncHandler},
|
||||
utils::WeakComponentLink,
|
||||
};
|
||||
|
||||
pub struct PageRemote {
|
||||
link: ComponentLink<Self>,
|
||||
@ -16,18 +22,24 @@ pub struct PageRemote {
|
||||
error_msg: String,
|
||||
fetch_task: Option<FetchTask>,
|
||||
connected: bool,
|
||||
handler: ProtocalHandler<VncHandler>,
|
||||
ws_link: WeakComponentLink<components::ws::WebsocketCtx>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Properties)]
|
||||
pub struct RemoteProps {}
|
||||
|
||||
pub enum RemoteMsg {
|
||||
Connect((String, u16)),
|
||||
ConnectResp(Result<Value, anyhow::Error>),
|
||||
Connected,
|
||||
Recv(Vec<u8>),
|
||||
Send(Vec<u8>),
|
||||
}
|
||||
|
||||
impl Component for PageRemote {
|
||||
type Message = RemoteMsg;
|
||||
type Properties = ();
|
||||
type Properties = RemoteProps;
|
||||
|
||||
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||
PageRemote {
|
||||
@ -36,6 +48,8 @@ impl Component for PageRemote {
|
||||
error_msg: String::from(""),
|
||||
fetch_task: None,
|
||||
connected: false,
|
||||
handler: ProtocalHandler::new(),
|
||||
ws_link: WeakComponentLink::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,9 +104,27 @@ impl Component for PageRemote {
|
||||
true
|
||||
}
|
||||
RemoteMsg::Recv(v) => {
|
||||
self.error_msg = String::from_utf8(v).unwrap();
|
||||
let out = self.handler.handle(&v);
|
||||
match out {
|
||||
ProtocalHandlerOutput::Err(err) => {
|
||||
self.error_msg = err.clone();
|
||||
true
|
||||
}
|
||||
ProtocalHandlerOutput::Ok => false,
|
||||
ProtocalHandlerOutput::WsBuf(out) => {
|
||||
self.link.send_message(RemoteMsg::Send(out));
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
RemoteMsg::Send(v) => {
|
||||
self.ws_link
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.send_message(WebsocketMsg::Send(Ok(v)));
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,10 +143,11 @@ impl Component for PageRemote {
|
||||
}
|
||||
} else {
|
||||
let recv_msg = self.link.callback(|v| RemoteMsg::Recv(v));
|
||||
let ws_link = &self.ws_link;
|
||||
html! {
|
||||
<>
|
||||
<components::ws::WebsocketCtx
|
||||
onrecv=recv_msg/>
|
||||
weak_link=ws_link onrecv=recv_msg/>
|
||||
{self.error_msg.clone()}
|
||||
</>
|
||||
}
|
||||
|
30
frontend/src/protocal/common.rs
Normal file
30
frontend/src/protocal/common.rs
Normal file
@ -0,0 +1,30 @@
|
||||
pub enum ProtocalHandlerOutput {
|
||||
Ok,
|
||||
WsBuf(Vec<u8>),
|
||||
Err(String),
|
||||
}
|
||||
|
||||
pub struct ProtocalHandler<T>
|
||||
where
|
||||
T: ProtocalImpl,
|
||||
{
|
||||
inner: T,
|
||||
}
|
||||
|
||||
impl<T> ProtocalHandler<T>
|
||||
where
|
||||
T: ProtocalImpl,
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
Self { inner: T::new() }
|
||||
}
|
||||
|
||||
pub fn handle(&mut self, input: &[u8]) -> ProtocalHandlerOutput {
|
||||
self.inner.handle(input)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ProtocalImpl {
|
||||
fn new() -> Self;
|
||||
fn handle(&mut self, input: &[u8]) -> ProtocalHandlerOutput;
|
||||
}
|
@ -1 +1,2 @@
|
||||
pub mod common;
|
||||
pub mod vnc;
|
||||
|
@ -1,5 +1,66 @@
|
||||
pub struct VncHandler {
|
||||
wsFrame: Vec<u8>,
|
||||
imageFrame: Vec<u8>,
|
||||
outputFrame: Vec<u8>,
|
||||
|
||||
|
||||
use yew::services::ConsoleService;
|
||||
|
||||
use super::common::*;
|
||||
|
||||
const VNC_RFB33: &[u8; 12] = b"RFB 003.003\n";
|
||||
const VNC_RFB37: &[u8; 12] = b"RFB 003.007\n";
|
||||
const VNC_RFB38: &[u8; 12] = b"RFB 003.008\n";
|
||||
|
||||
enum VncState {
|
||||
Handshake,
|
||||
Authentication,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum SecurityType {
|
||||
Unknown(u8),
|
||||
Invalid,
|
||||
None,
|
||||
VncAuth,
|
||||
AppleRdp,
|
||||
}
|
||||
|
||||
pub struct VncHandler {
|
||||
state: VncState,
|
||||
output: Vec<u8>,
|
||||
}
|
||||
|
||||
impl ProtocalImpl for VncHandler {
|
||||
fn new() -> Self {
|
||||
VncHandler {
|
||||
state: VncState::Handshake,
|
||||
output: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle(&mut self, input: &[u8]) -> ProtocalHandlerOutput {
|
||||
match self.state {
|
||||
VncState::Handshake => {
|
||||
self.handle_handshake(input);
|
||||
self.state = VncState::Authentication;
|
||||
return ProtocalHandlerOutput::WsBuf(self.output.clone());
|
||||
}
|
||||
VncState::Authentication => {
|
||||
ConsoleService::log(&format!("{:?}", input));
|
||||
return ProtocalHandlerOutput::Ok;
|
||||
}
|
||||
_ => panic!("unsupported version"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private methods
|
||||
impl VncHandler {
|
||||
fn handle_handshake(&mut self, rfbversion: &[u8]) {
|
||||
match rfbversion {
|
||||
b"RFB 003.008\n" => {
|
||||
for b in VNC_RFB33 {
|
||||
self.output.push(*b);
|
||||
}
|
||||
}
|
||||
_ => panic!("unsupported version"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,9 @@
|
||||
use std::{cell::RefCell, ops::Deref, rc::Rc};
|
||||
use yew::{
|
||||
html::{ComponentLink, ImplicitClone},
|
||||
Component,
|
||||
};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn set_panic_hook() {
|
||||
// When the `console_error_panic_hook` feature is enabled, we can call the
|
||||
@ -9,3 +15,35 @@ pub fn set_panic_hook() {
|
||||
#[cfg(feature = "console_error_panic_hook")]
|
||||
console_error_panic_hook::set_once();
|
||||
}
|
||||
|
||||
// ComponentLink for sending message
|
||||
// Option to be default none, later assign a vaule
|
||||
// RefCell for container, mutable reference
|
||||
// Rc for multiple ownership
|
||||
pub struct WeakComponentLink<COMP: Component>(Rc<RefCell<Option<ComponentLink<COMP>>>>);
|
||||
impl<COMP: Component> Clone for WeakComponentLink<COMP> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(Rc::clone(&self.0))
|
||||
}
|
||||
}
|
||||
impl<COMP: Component> ImplicitClone for WeakComponentLink<COMP> {}
|
||||
|
||||
impl<COMP: Component> Default for WeakComponentLink<COMP> {
|
||||
fn default() -> Self {
|
||||
Self(Rc::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<COMP: Component> Deref for WeakComponentLink<COMP> {
|
||||
type Target = Rc<RefCell<Option<ComponentLink<COMP>>>>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<COMP: Component> PartialEq for WeakComponentLink<COMP> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
Rc::ptr_eq(&self.0, &other.0)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user