1use bitflags::bitflags;
8use futures::future::BoxFuture;
9use futures::FutureExt;
10use thiserror::Error;
11use tokio::io::{AsyncReadExt, AsyncWriteExt};
12use tokio::io::{AsyncRead,AsyncWrite};
13
14use crate::encodings::{Encoding, EncodingType};
15use crate::keysym::KeySym;
16use crate::pixel_formats::rgb_888;
17
18#[derive(Debug, Error)]
19pub enum ProtocolError {
20 #[error("invalid protocol version message")]
21 InvalidProtocolVersion,
22
23 #[error("invalid security type message ({0})")]
24 InvalidSecurityType(u8),
25
26 #[error("invalid text encoding")]
27 InvalidTextEncoding,
28
29 #[error("unknown client message type ({0})")]
30 UnknownClientMessageType(u8),
31
32 #[error(transparent)]
33 KeySymError(#[from] crate::keysym::KeySymError),
34
35 #[error("I/O error: {0}")]
36 Io(#[from] std::io::Error),
37}
38
39pub trait ReadMessage {
40 fn read_from<'a>(stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<Self, ProtocolError>>
41 where
42 Self: Sized;
43}
44
45pub trait WriteMessage {
46 fn write_to<'a>(self, stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<(), ProtocolError>>;
47}
48
49#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
50pub enum ProtoVersion {
51 Rfb33,
52 Rfb37,
53 Rfb38,
54}
55
56impl ReadMessage for ProtoVersion {
57 fn read_from<'a>(stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<Self, ProtocolError>> {
58 async move {
59 let mut buf = [0u8; 12];
60 stream.read_exact(&mut buf).await?;
61
62 match &buf {
63 b"RFB 003.003\n" => Ok(ProtoVersion::Rfb33),
64 b"RFB 003.007\n" => Ok(ProtoVersion::Rfb37),
65 b"RFB 003.008\n" => Ok(ProtoVersion::Rfb38),
66 _ => Err(ProtocolError::InvalidProtocolVersion),
67 }
68 }
69 .boxed()
70 }
71}
72
73impl WriteMessage for ProtoVersion {
74 fn write_to<'a>(self, stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<(), ProtocolError>> {
75 async move {
76 let s = match self {
77 ProtoVersion::Rfb33 => b"RFB 003.003\n",
78 ProtoVersion::Rfb37 => b"RFB 003.007\n",
79 ProtoVersion::Rfb38 => b"RFB 003.008\n",
80 };
81
82 Ok(stream.write_all(s).await?)
83 }
84 .boxed()
85 }
86}
87
88#[derive(Debug, Clone)]
90pub struct SecurityTypes(pub Vec<SecurityType>);
91
92#[derive(Clone, PartialEq, Debug)]
93pub enum SecurityType {
94 None,
95 VncAuthentication,
96}
97
98impl WriteMessage for SecurityTypes {
99 fn write_to<'a>(self, stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<(), ProtocolError>> {
100 async move {
101 stream.write_u8(self.0.len() as u8).await?;
103 for t in self.0.into_iter() {
104 t.write_to(stream).await?;
105 }
106
107 Ok(())
108 }
109 .boxed()
110 }
111}
112
113impl ReadMessage for SecurityType {
114 fn read_from<'a>(stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<Self, ProtocolError>> {
115 async move {
116 let t = stream.read_u8().await?;
117 match t {
118 1 => Ok(SecurityType::None),
119 2 => Ok(SecurityType::VncAuthentication),
120 v => Err(ProtocolError::InvalidSecurityType(v)),
121 }
122 }
123 .boxed()
124 }
125}
126
127impl WriteMessage for SecurityType {
128 fn write_to<'a>(self, stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<(), ProtocolError>> {
129 async move {
130 let val = match self {
131 SecurityType::None => 0,
132 SecurityType::VncAuthentication => 1,
133 };
134 stream.write_u8(val).await?;
135
136 Ok(())
137 }
138 .boxed()
139 }
140}
141
142pub enum SecurityResult {
144 Success,
145 Failure(String),
146}
147
148impl WriteMessage for SecurityResult {
149 fn write_to<'a>(self, stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<(), ProtocolError>> {
150 async move {
151 match self {
152 SecurityResult::Success => {
153 stream.write_u32(0).await?;
154 }
155 SecurityResult::Failure(s) => {
156 stream.write_u32(1).await?;
157 stream.write_all(s.as_bytes()).await?;
158 }
159 };
160
161 Ok(())
162 }
163 .boxed()
164 }
165}
166
167#[derive(Debug)]
169pub struct ClientInit {
170 pub shared: bool,
171}
172
173impl ReadMessage for ClientInit {
174 fn read_from<'a>(stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<Self, ProtocolError>> {
175 async {
176 let flag = stream.read_u8().await?;
177 match flag {
178 0 => Ok(ClientInit { shared: false }),
179 _ => Ok(ClientInit { shared: true }),
180 }
181 }
182 .boxed()
183 }
184}
185
186#[derive(Debug)]
188pub struct ServerInit {
189 initial_res: Resolution,
190 pixel_format: PixelFormat,
191 name: String,
192}
193
194impl ServerInit {
195 pub fn new(width: u16, height: u16, name: String, pixel_format: PixelFormat) -> Self {
196 Self {
197 initial_res: Resolution { width, height },
198 pixel_format,
199 name,
200 }
201 }
202}
203
204impl WriteMessage for ServerInit {
205 fn write_to<'a>(self, stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<(), ProtocolError>> {
206 async move {
207 self.initial_res.write_to(stream).await?;
208 self.pixel_format.write_to(stream).await?;
209
210 stream.write_u32(self.name.len() as u32).await?;
212 stream.write_all(self.name.as_bytes()).await?;
213
214 Ok(())
215 }
216 .boxed()
217 }
218}
219
220pub enum _ServerMessage {
221 FramebufferUpdate(FramebufferUpdate),
222 SetColorMapEntries(SetColorMapEntries),
223 Bell,
224 ServerCutText(CutText),
225}
226
227pub struct FramebufferUpdate {
228 rectangles: Vec<Rectangle>,
229}
230
231impl FramebufferUpdate {
232 pub fn new(rectangles: Vec<Rectangle>) -> Self {
233 FramebufferUpdate { rectangles }
234 }
235
236 pub fn transform(&self, input_pf: &PixelFormat, output_pf: &PixelFormat) -> Self {
237 let mut rectangles = Vec::new();
238
239 for r in self.rectangles.iter() {
240 rectangles.push(r.transform(input_pf, output_pf));
241 }
242
243 FramebufferUpdate { rectangles }
244 }
245}
246
247#[derive(Debug, Copy, Clone)]
248pub(crate) struct Position {
249 x: u16,
250 y: u16,
251}
252
253impl ReadMessage for Position {
254 fn read_from<'a>(stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<Self, ProtocolError>> {
255 async {
256 let x = stream.read_u16().await?;
257 let y = stream.read_u16().await?;
258
259 Ok(Position { x, y })
260 }
261 .boxed()
262 }
263}
264
265#[derive(Debug, Copy, Clone)]
266pub(crate) struct Resolution {
267 width: u16,
268 height: u16,
269}
270
271impl ReadMessage for Resolution {
272 fn read_from<'a>(stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<Self, ProtocolError>> {
273 async {
274 let width = stream.read_u16().await?;
275 let height = stream.read_u16().await?;
276
277 Ok(Resolution { width, height })
278 }
279 .boxed()
280 }
281}
282
283impl WriteMessage for Resolution {
284 fn write_to<'a>(self, stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<(), ProtocolError>> {
285 async move {
286 stream.write_u16(self.width).await?;
287 stream.write_u16(self.height).await?;
288 Ok(())
289 }
290 .boxed()
291 }
292}
293
294pub struct Rectangle {
295 position: Position,
296 dimensions: Resolution,
297 data: Box<dyn Encoding>,
298}
299
300impl Rectangle {
301 pub fn new(x: u16, y: u16, width: u16, height: u16, data: Box<dyn Encoding>) -> Self {
302 Rectangle {
303 position: Position { x, y },
304 dimensions: Resolution { width, height },
305 data,
306 }
307 }
308
309 pub fn transform(&self, input_pf: &PixelFormat, output_pf: &PixelFormat) -> Self {
310 Rectangle {
311 position: self.position,
312 dimensions: self.dimensions,
313 data: self.data.transform(input_pf, output_pf),
314 }
315 }
316}
317
318impl WriteMessage for Rectangle {
319 fn write_to<'a>(self, stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<(), ProtocolError>> {
320 async move {
321 let encoding_type: i32 = self.data.get_type().into();
322
323 stream.write_u16(self.position.x).await?;
324 stream.write_u16(self.position.y).await?;
325 stream.write_u16(self.dimensions.width).await?;
326 stream.write_u16(self.dimensions.height).await?;
327 stream.write_i32(encoding_type).await?;
328
329 let data = self.data.encode();
330 stream.write_all(data).await?;
331
332 Ok(())
333 }
334 .boxed()
335 }
336}
337
338impl WriteMessage for FramebufferUpdate {
339 fn write_to<'a>(self, stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<(), ProtocolError>> {
340 async move {
341 stream.write_u8(0).await?;
343
344 stream.write_u8(0).await?;
346
347 let n_rect = self.rectangles.len() as u16;
349 stream.write_u16(n_rect).await?;
350
351 for r in self.rectangles.into_iter() {
353 r.write_to(stream).await?;
354 }
355
356 Ok(())
357 }
358 .boxed()
359 }
360}
361
362#[derive(Debug)]
363pub struct SetColorMapEntries {
364 _colors: Vec<_ColorMapEntry>,
365}
366
367#[derive(Debug)]
368pub struct _ColorMapEntry {
369 _color: u16,
370 _red: u16,
371 _blue: u16,
372 _green: u16,
373}
374
375#[derive(Debug)]
378pub struct CutText {
379 _text: String,
380}
381
382#[derive(Debug, Clone, PartialEq)]
384pub struct PixelFormat {
385 pub bits_per_pixel: u8, pub depth: u8, pub big_endian: bool,
388 pub color_spec: ColorSpecification,
389}
390
391impl PixelFormat {
392 pub fn new_colorformat(
394 bbp: u8,
395 depth: u8,
396 big_endian: bool,
397 red_shift: u8,
398 red_max: u16,
399 green_shift: u8,
400 green_max: u16,
401 blue_shift: u8,
402 blue_max: u16,
403 ) -> Self {
404 PixelFormat {
405 bits_per_pixel: bbp,
406 depth,
407 big_endian,
408 color_spec: ColorSpecification::ColorFormat(ColorFormat {
409 red_max,
410 green_max,
411 blue_max,
412 red_shift,
413 green_shift,
414 blue_shift,
415 }),
416 }
417 }
418
419 pub fn is_rgb_888(&self) -> bool {
421 if self.bits_per_pixel != rgb_888::BITS_PER_PIXEL || self.depth != rgb_888::DEPTH {
422 return false;
423 }
424
425 match &self.color_spec {
426 ColorSpecification::ColorFormat(cf) => {
427 (cf.red_max == rgb_888::MAX_VALUE)
428 && (cf.green_max == rgb_888::MAX_VALUE)
429 && (cf.blue_max == rgb_888::MAX_VALUE)
430 && (rgb_888::valid_shift(cf.red_shift))
431 && (rgb_888::valid_shift(cf.green_shift))
432 && (rgb_888::valid_shift(cf.blue_shift))
433 }
434 ColorSpecification::ColorMap(_) => false,
435 }
436 }
437}
438
439impl ReadMessage for PixelFormat {
440 fn read_from<'a>(stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<Self, ProtocolError>> {
441 async {
442 let bits_per_pixel = stream.read_u8().await?;
443 let depth = stream.read_u8().await?;
444 let be_flag = stream.read_u8().await?;
445 let big_endian = match be_flag {
446 0 => false,
447 _ => true,
448 };
449 let color_spec = ColorSpecification::read_from(stream).await?;
450
451 let mut buf = [0u8; 3];
453 stream.read_exact(&mut buf).await?;
454
455 Ok(Self {
456 bits_per_pixel,
457 depth,
458 big_endian,
459 color_spec,
460 })
461 }
462 .boxed()
463 }
464}
465
466impl WriteMessage for PixelFormat {
467 fn write_to<'a>(self, stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<(), ProtocolError>> {
468 async move {
469 stream.write_u8(self.bits_per_pixel).await?;
470 stream.write_u8(self.depth).await?;
471 stream.write_u8(if self.big_endian { 1 } else { 0 }).await?;
472 self.color_spec.write_to(stream).await?;
473
474 let buf = [0u8; 3];
476 stream.write_all(&buf).await?;
477
478 Ok(())
479 }
480 .boxed()
481 }
482}
483
484#[derive(Debug, Clone, PartialEq)]
485#[allow(dead_code)]
486pub enum ColorSpecification {
487 ColorFormat(ColorFormat),
488 ColorMap(ColorMap), }
490
491#[derive(Debug, Clone, PartialEq)]
492pub struct ColorFormat {
493 pub red_max: u16,
495 pub green_max: u16,
496 pub blue_max: u16,
497 pub red_shift: u8,
498 pub green_shift: u8,
499 pub blue_shift: u8,
500}
501
502#[derive(Debug, Clone, PartialEq)]
503pub struct ColorMap {}
504
505impl ReadMessage for ColorSpecification {
506 fn read_from<'a>(stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<Self, ProtocolError>> {
507 async {
508 let tc_flag = stream.read_u8().await?;
509 match tc_flag {
510 0 => {
511 unimplemented!()
513 }
514 _ => {
515 let red_max = stream.read_u16().await?;
517 let green_max = stream.read_u16().await?;
518 let blue_max = stream.read_u16().await?;
519
520 let red_shift = stream.read_u8().await?;
521 let green_shift = stream.read_u8().await?;
522 let blue_shift = stream.read_u8().await?;
523
524 Ok(ColorSpecification::ColorFormat(ColorFormat {
525 red_max,
526 green_max,
527 blue_max,
528 red_shift,
529 green_shift,
530 blue_shift,
531 }))
532 }
533 }
534 }
535 .boxed()
536 }
537}
538
539impl WriteMessage for ColorSpecification {
540 fn write_to<'a>(self, stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<(), ProtocolError>> {
541 async move {
542 match self {
543 ColorSpecification::ColorFormat(cf) => {
544 stream.write_u8(1).await?; stream.write_u16(cf.red_max).await?;
546 stream.write_u16(cf.green_max).await?;
547 stream.write_u16(cf.blue_max).await?;
548
549 stream.write_u8(cf.red_shift).await?;
550 stream.write_u8(cf.green_shift).await?;
551 stream.write_u8(cf.blue_shift).await?;
552 }
553 ColorSpecification::ColorMap(_cm) => {
554 unimplemented!()
555 }
556 };
557
558 Ok(())
559 }
560 .boxed()
561 }
562}
563
564pub enum ClientMessage {
566 SetPixelFormat(PixelFormat),
567 SetEncodings(Vec<EncodingType>),
568 FramebufferUpdateRequest(FramebufferUpdateRequest),
569 KeyEvent(KeyEvent),
570 PointerEvent(PointerEvent),
571 ClientCutText(String),
572}
573
574impl ReadMessage for ClientMessage {
575 fn read_from<'a>(
576 stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync),
577 ) -> BoxFuture<'a, Result<ClientMessage, ProtocolError>> {
578 async {
579 let t = stream.read_u8().await?;
580 let res = match t {
581 0 => {
582 let mut padding = [0u8; 3];
584 stream.read_exact(&mut padding).await?;
585 let pixel_format = PixelFormat::read_from(stream).await?;
586 Ok(ClientMessage::SetPixelFormat(pixel_format))
587 }
588
589 2 => {
590 stream.read_u8().await?; let num_encodings = stream.read_u16().await?;
593
594 let mut encodings = Vec::new();
597 for _ in 0..num_encodings {
598 let e: EncodingType = stream.read_i32().await?.into();
599 encodings.push(e);
600 }
601
602 Ok(ClientMessage::SetEncodings(encodings))
603 }
604 3 => {
605 let incremental = match stream.read_u8().await? {
607 0 => false,
608 _ => true,
609 };
610 let position = Position::read_from(stream).await?;
611 let resolution = Resolution::read_from(stream).await?;
612
613 let fbu_req = FramebufferUpdateRequest {
614 incremental,
615 position,
616 resolution,
617 };
618
619 Ok(ClientMessage::FramebufferUpdateRequest(fbu_req))
620 }
621 4 => {
622 let is_pressed = match stream.read_u8().await? {
624 0 => false,
625 _ => true,
626 };
627
628 stream.read_u16().await?;
630
631 let keysym_raw = stream.read_u32().await?;
632 let keysym = KeySym::try_from(keysym_raw)?;
633
634 let key_event = KeyEvent {
635 is_pressed,
636 keysym,
637 keysym_raw,
638 };
639
640 Ok(ClientMessage::KeyEvent(key_event))
641 }
642 5 => {
643 let pointer_event = PointerEvent::read_from(stream).await?;
645 Ok(ClientMessage::PointerEvent(pointer_event))
646 }
647 6 => {
648 let mut padding = [0u8; 3];
652 stream.read_exact(&mut padding).await?;
653
654 let len = stream.read_u32().await?;
655 let mut buf: Vec<u8> = Vec::with_capacity(len as usize);
656 stream.read_exact(&mut buf).await?;
657
658 let text =
661 String::from_utf8(buf).map_err(|_| ProtocolError::InvalidTextEncoding)?;
662
663 Ok(ClientMessage::ClientCutText(text))
664 }
665 unknown => Err(ProtocolError::UnknownClientMessageType(unknown)),
666 };
667
668 res
669 }
670 .boxed()
671 }
672}
673
674#[derive(Debug)]
675#[allow(dead_code)]
676pub struct FramebufferUpdateRequest {
677 incremental: bool,
678 position: Position,
679 resolution: Resolution,
680}
681
682#[derive(Debug, Copy, Clone)]
683pub struct KeyEvent {
684 is_pressed: bool,
685 keysym: KeySym,
686 keysym_raw: u32,
687}
688
689impl KeyEvent {
690 pub fn keysym_raw(&self) -> u32 {
691 self.keysym_raw
692 }
693
694 pub fn keysym(&self) -> KeySym {
695 self.keysym
696 }
697
698 pub fn is_pressed(&self) -> bool {
699 self.is_pressed
700 }
701}
702
703bitflags! {
704 #[derive(Debug)]
705 struct MouseButtons: u8 {
706 const LEFT = 1 << 0;
707 const MIDDLE = 1 << 1;
708 const RIGHT = 1 << 2;
709 const SCROLL_A = 1 << 3;
710 const SCROLL_B = 1 << 4;
711 const SCROLL_C = 1 << 5;
712 const SCROLL_D = 1 << 6;
713 }
714}
715
716#[derive(Debug)]
717#[allow(dead_code)]
718pub struct PointerEvent {
719 position: Position,
720 pressed: MouseButtons,
721}
722
723impl ReadMessage for PointerEvent {
724 fn read_from<'a>(stream: &'a mut (impl AsyncRead + AsyncWrite + Unpin + Send + Sync)) -> BoxFuture<'a, Result<Self, ProtocolError>> {
725 async {
726 let button_mask = stream.read_u8().await?;
727 let pressed = MouseButtons::from_bits_truncate(button_mask);
728 let position = Position::read_from(stream).await?;
729
730 Ok(PointerEvent { position, pressed })
731 }
732 .boxed()
733 }
734}