cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

App.js (4629B)


      1import React from 'react';
      2import Guacamole from 'guacamole-common-js';
      3import crypto from "crypto";
      4import { Buffer } from 'buffer';
      5import './App.css';
      6
      7const CIPHER = 'aes-256-cbc';
      8// const KEY = 'x9h9Ab3Bhz0LTleMygDVQQvkqWocr5EV';
      9// const KEY = 'https://en.wikipedia.org/wiki/Security_through_obscurity'.substring(0, 32);
     10const KEY = "https://en.wikipedia.org/wiki/Se";
     11
     12function encryptToken(value) {
     13  const iv = crypto.randomBytes(16);
     14  const cipher = crypto.createCipheriv(CIPHER, Buffer.from(KEY), iv);
     15
     16  let encrypted = cipher.update(JSON.stringify(value), 'utf8', 'base64');
     17  encrypted += cipher.final('base64');
     18
     19  const data = {
     20    iv: iv.toString('base64'),
     21    value: encrypted
     22  };
     23
     24  const json = JSON.stringify(data);
     25  return Buffer.from(json).toString('base64');
     26}
     27
     28
     29const GuacamoleApp = () => {
     30  var guac_backend_host = process.env.REACT_APP_GUAC_BACKEND_HOSTNAME;
     31  var win_server_host = process.env.REACT_APP_WIN_SERVER_HOSTNAME;
     32
     33  const handleSelectSSH = (event) => {
     34    document.getElementById("port").value = "50022";
     35    document.getElementById("ssh").checked = true;
     36  }
     37
     38  const handleSelectRDP = (event) => {
     39    document.getElementById("port").value = "3389";
     40    document.getElementById("rdp").checked = true;
     41  }
     42
     43  const handleSelectVNC = (event) => {
     44    document.getElementById("port").value = "5900";
     45    document.getElementById("vnc").checked = true;
     46  }
     47
     48  const openGc = async () => {
     49    window.Buffer = Buffer;
     50    try {
     51      var ele = document.getElementsByTagName('input');
     52      var protocol_type = "";
     53      var port = document.getElementById("port").value;
     54      for (var i = 0; i < ele.length; i++) {
     55        if (ele[i].type === "radio") {
     56          if (ele[i].checked)
     57            protocol_type = ele[i].value;
     58        }
     59      }
     60      const tokenObject = {
     61        connection: {
     62          type: protocol_type,
     63          settings: {
     64            "hostname": win_server_host,
     65            "username": "Administrator",
     66            "port": port,
     67            "password": "vagrant",
     68            "security": "any",
     69            "ignore-cert": true,
     70            "enable-wallpaper": true
     71          }
     72        }
     73      };
     74
     75      const token = encryptToken(tokenObject);
     76      var wsurl = guac_backend_host;
     77      console.log(wsurl);
     78      const gc = await new Guacamole.Client(new Guacamole.WebSocketTunnel(wsurl));
     79      const display = document.getElementById('gcdisplay');
     80      const element = gc.getDisplay().getElement();
     81
     82      if (display) {
     83        display?.appendChild(element);
     84      }
     85
     86      gc.connect(`token=${token}&height=800&width=` + document.getElementById("gcdisplay").offsetWidth.toString());
     87
     88      // Error handler
     89      gc.onerror = (error) => console.log(error.message);
     90      window.onunload = () => gc.disconnect();
     91
     92      // Mouse
     93      const mouse = new Guacamole.Mouse(gc.getDisplay().getElement());
     94
     95
     96      // Forward all mouse interaction over Guacamole connection
     97      mouse.onEach(['mousedown', 'mousemove', 'mouseup'], function sendMouseEvent(e) {
     98        gc.sendMouseState(e.state, true);
     99      });
    100
    101
    102      // Hide software cursor when mouse leaves display
    103      mouse.on('mouseout', function hideCursor() {
    104        gc.getDisplay().showCursor(false);
    105      });
    106      const keyboard = new Guacamole.Keyboard(document);
    107      keyboard.onkeydown = (keysym) => gc.sendKeyEvent(1, keysym);
    108      keyboard.onkeyup = (keysym) => gc.sendKeyEvent(0, keysym);
    109
    110    } catch (error) {
    111      console.log("GC Error", error);
    112    }
    113  }
    114  return <div style={{ width: '100%' }}>
    115    <h1>Guacamole Connect RDP/SSH/VNC</h1>
    116    <fieldset width="100px">
    117      <legend>Select your connection method</legend>
    118
    119      <div>
    120        <input type="radio" id="ssh" name="connection_type" value="ssh" onChange={handleSelectSSH} />
    121        <label htmlFor="SSH">SSH</label>
    122      </div>
    123
    124      <div>
    125        <input type="radio" id="rdp" name="connection_type" value="rdp" onChange={handleSelectRDP} />
    126        <label htmlFor="RDP">RDP</label>
    127      </div>
    128
    129      <div>
    130        <input type="radio" id="vnc" name="connection_type" value="vnc" onChange={handleSelectVNC} />
    131        <label htmlFor="VNC">VNC</label>
    132      </div>
    133
    134    </fieldset>
    135    <div>
    136      Port:
    137      <input type="text" id="port" name="port" defaultValue="3389" />
    138    </div>
    139    <div>
    140      Session ID:
    141      <input type="text" id="session" name="session" defaultValue="" />
    142    </div>
    143    <br></br>
    144    <button onClick={openGc}>Open Guacamole</button>
    145    <br />
    146    <div className="box">
    147      <div id='gcdisplay' className="content"><p>content</p></div>
    148    </div>
    149  </div>
    150}
    151export default GuacamoleApp;
    152