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