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::services::ConsoleService;
|
||||||
use yew::{format::Binary, utils::host};
|
use yew::{format::Binary, utils::host};
|
||||||
|
|
||||||
|
use crate::utils::WeakComponentLink;
|
||||||
|
|
||||||
pub struct WebsocketCtx {
|
pub struct WebsocketCtx {
|
||||||
ws: Option<WebSocketTask>,
|
ws: Option<WebSocketTask>,
|
||||||
link: ComponentLink<Self>,
|
link: ComponentLink<Self>,
|
||||||
@ -14,6 +16,7 @@ pub struct WebsocketCtx {
|
|||||||
pub struct WebsocketProps {
|
pub struct WebsocketProps {
|
||||||
#[prop_or_default]
|
#[prop_or_default]
|
||||||
pub onrecv: Callback<Vec<u8>>,
|
pub onrecv: Callback<Vec<u8>>,
|
||||||
|
pub weak_link: WeakComponentLink<WebsocketCtx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum WebsocketMsg {
|
pub enum WebsocketMsg {
|
||||||
@ -29,6 +32,7 @@ impl Component for WebsocketCtx {
|
|||||||
type Properties = WebsocketProps;
|
type Properties = WebsocketProps;
|
||||||
|
|
||||||
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
|
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||||
|
props.weak_link.borrow_mut().replace(link.clone());
|
||||||
Self {
|
Self {
|
||||||
ws: None,
|
ws: None,
|
||||||
link: link,
|
link: link,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
mod app;
|
mod app;
|
||||||
mod components;
|
mod components;
|
||||||
mod pages;
|
mod pages;
|
||||||
|
mod protocal;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use yew::{
|
use yew::{
|
||||||
format::Json,
|
format::Json,
|
||||||
|
html,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
services::{
|
services::{
|
||||||
fetch::{FetchTask, Request, Response},
|
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 {
|
pub struct PageRemote {
|
||||||
link: ComponentLink<Self>,
|
link: ComponentLink<Self>,
|
||||||
@ -16,18 +22,24 @@ pub struct PageRemote {
|
|||||||
error_msg: String,
|
error_msg: String,
|
||||||
fetch_task: Option<FetchTask>,
|
fetch_task: Option<FetchTask>,
|
||||||
connected: bool,
|
connected: bool,
|
||||||
|
handler: ProtocalHandler<VncHandler>,
|
||||||
|
ws_link: WeakComponentLink<components::ws::WebsocketCtx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Properties)]
|
||||||
|
pub struct RemoteProps {}
|
||||||
|
|
||||||
pub enum RemoteMsg {
|
pub enum RemoteMsg {
|
||||||
Connect((String, u16)),
|
Connect((String, u16)),
|
||||||
ConnectResp(Result<Value, anyhow::Error>),
|
ConnectResp(Result<Value, anyhow::Error>),
|
||||||
Connected,
|
Connected,
|
||||||
Recv(Vec<u8>),
|
Recv(Vec<u8>),
|
||||||
|
Send(Vec<u8>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for PageRemote {
|
impl Component for PageRemote {
|
||||||
type Message = RemoteMsg;
|
type Message = RemoteMsg;
|
||||||
type Properties = ();
|
type Properties = RemoteProps;
|
||||||
|
|
||||||
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
|
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
|
||||||
PageRemote {
|
PageRemote {
|
||||||
@ -36,6 +48,8 @@ impl Component for PageRemote {
|
|||||||
error_msg: String::from(""),
|
error_msg: String::from(""),
|
||||||
fetch_task: None,
|
fetch_task: None,
|
||||||
connected: false,
|
connected: false,
|
||||||
|
handler: ProtocalHandler::new(),
|
||||||
|
ws_link: WeakComponentLink::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,9 +104,27 @@ impl Component for PageRemote {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
RemoteMsg::Recv(v) => {
|
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
|
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 {
|
} else {
|
||||||
let recv_msg = self.link.callback(|v| RemoteMsg::Recv(v));
|
let recv_msg = self.link.callback(|v| RemoteMsg::Recv(v));
|
||||||
|
let ws_link = &self.ws_link;
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<components::ws::WebsocketCtx
|
<components::ws::WebsocketCtx
|
||||||
onrecv=recv_msg/>
|
weak_link=ws_link onrecv=recv_msg/>
|
||||||
{self.error_msg.clone()}
|
{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;
|
pub mod vnc;
|
||||||
|
@ -1,5 +1,66 @@
|
|||||||
pub struct VncHandler {
|
|
||||||
wsFrame: Vec<u8>,
|
|
||||||
imageFrame: Vec<u8>,
|
use yew::services::ConsoleService;
|
||||||
outputFrame: Vec<u8>,
|
|
||||||
|
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)]
|
#[allow(dead_code)]
|
||||||
pub fn set_panic_hook() {
|
pub fn set_panic_hook() {
|
||||||
// When the `console_error_panic_hook` feature is enabled, we can call the
|
// 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")]
|
#[cfg(feature = "console_error_panic_hook")]
|
||||||
console_error_panic_hook::set_once();
|
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